1
19
20 package com.liferay.portal.tools;
21
22 import com.liferay.portal.kernel.plugin.PluginPackage;
23 import com.liferay.portal.kernel.util.FileUtil;
24 import com.liferay.portal.kernel.util.ServerDetector;
25 import com.liferay.portal.kernel.util.Validator;
26 import com.liferay.portal.kernel.xml.Document;
27 import com.liferay.portal.kernel.xml.Element;
28 import com.liferay.portal.kernel.xml.SAXReaderUtil;
29 import com.liferay.portal.model.Plugin;
30 import com.liferay.portal.util.InitUtil;
31 import com.liferay.portal.util.Portal;
32 import com.liferay.portal.util.PortalUtil;
33 import com.liferay.portal.util.PrefsPropsUtil;
34 import com.liferay.portal.util.PropsKeys;
35 import com.liferay.portal.util.PropsValues;
36 import com.liferay.portal.xml.DocumentImpl;
37 import com.liferay.util.TextFormatter;
38 import com.liferay.util.xml.XMLMerger;
39 import com.liferay.util.xml.descriptor.FacesXMLDescriptor;
40
41 import java.io.File;
42
43 import java.util.ArrayList;
44 import java.util.HashMap;
45 import java.util.Iterator;
46 import java.util.List;
47 import java.util.Map;
48 import java.util.Properties;
49
50
57 public class PortletDeployer extends BaseDeployer {
58
59 public static final String JSF_MYFACES =
60 "org.apache.myfaces.portlet.MyFacesGenericPortlet";
61
62 public static final String JSF_SUN =
63 "com.sun.faces.portlet.FacesPortlet";
64
65 public static final String LIFERAY_RENDER_KIT_FACTORY =
66 "com.liferay.util.jsf.sun.faces.renderkit.LiferayRenderKitFactoryImpl";
67
68 public static final String MYFACES_CONTEXT_FACTORY =
69 "com.liferay.util.bridges.jsf.myfaces.MyFacesContextFactoryImpl";
70
71 public static void main(String[] args) {
72 InitUtil.initWithSpring();
73
74 List<String> wars = new ArrayList<String>();
75 List<String> jars = new ArrayList<String>();
76
77 for (String arg : args) {
78 if (arg.endsWith(".war")) {
79 wars.add(arg);
80 }
81 else if (arg.endsWith(".jar")) {
82 jars.add(arg);
83 }
84 }
85
86 new PortletDeployer(wars, jars);
87 }
88
89 protected PortletDeployer() {
90 }
91
92 protected PortletDeployer(List<String> wars, List<String> jars) {
93 super(wars, jars);
94 }
95
96 protected void checkArguments() {
97 super.checkArguments();
98
99 if (Validator.isNull(portletTaglibDTD)) {
100 throw new IllegalArgumentException(
101 "The system property deployer.portlet.taglib.dtd is not set");
102 }
103 }
104
105 protected void copyXmls(
106 File srcFile, String displayName, PluginPackage pluginPackage)
107 throws Exception {
108
109 super.copyXmls(srcFile, displayName, pluginPackage);
110
111 if (appServerType.equals(ServerDetector.TOMCAT_ID)) {
112 copyDependencyXml("context.xml", srcFile + "/META-INF");
113 }
114 }
115
116 protected String getExtraContent(
117 double webXmlVersion, File srcFile, String displayName)
118 throws Exception {
119
120 StringBuilder sb = new StringBuilder();
121
122 String extraContent = super.getExtraContent(
123 webXmlVersion, srcFile, displayName);
124
125 sb.append(extraContent);
126
127 if (ServerDetector.isWebSphere()) {
128 sb.append("<context-param>");
129 sb.append("<param-name>");
130 sb.append("com.ibm.websphere.portletcontainer.");
131 sb.append("PortletDeploymentEnabled");
132 sb.append("</param-name>");
133 sb.append("<param-value>false</param-value>");
134 sb.append("</context-param>");
135 }
136
137 File facesXML = new File(srcFile + "/WEB-INF/faces-config.xml");
138 File portletXML = new File(
139 srcFile + "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_STANDARD);
140 File webXML = new File(srcFile + "/WEB-INF/web.xml");
141
142 sb.append(getServletContent(portletXML, webXML));
143
144 setupJSF(facesXML, portletXML);
145
146 if (_sunFacesPortlet) {
147
148
150 sb.append("<listener>");
151 sb.append("<listener-class>");
152 sb.append("com.liferay.util.bridges.jsf.sun.");
153 sb.append("LiferayConfigureListener");
154 sb.append("</listener-class>");
155 sb.append("</listener>");
156 }
157
158
160 sb.append("<listener>");
161 sb.append("<listener-class>");
162 sb.append("com.liferay.portal.kernel.servlet.PortletContextListener");
163 sb.append("</listener-class>");
164 sb.append("</listener>");
165
166
168 sb.append(getSpeedFiltersContent(srcFile));
169
170 return sb.toString();
171 }
172
173 protected String getServletContent(File portletXML, File webXML)
174 throws Exception {
175
176 StringBuilder sb = new StringBuilder();
177
178
180 Document doc = SAXReaderUtil.read(portletXML);
181
182 Element root = doc.getRootElement();
183
184 Iterator<Element> itr1 = root.elements("portlet").iterator();
185
186 while (itr1.hasNext()) {
187 Element portlet = itr1.next();
188
189 String portletName = PortalUtil.getJsSafePortletId(
190 portlet.elementText("portlet-name"));
191 String portletClass = portlet.elementText("portlet-class");
192
193 sb.append("<servlet>");
194 sb.append("<servlet-name>");
195 sb.append(portletName);
196 sb.append("</servlet-name>");
197 sb.append("<servlet-class>");
198 sb.append("com.liferay.portal.kernel.servlet.PortletServlet");
199 sb.append("</servlet-class>");
200 sb.append("<init-param>");
201 sb.append("<param-name>portlet-class</param-name>");
202 sb.append("<param-value>");
203 sb.append(portletClass);
204 sb.append("</param-value>");
205 sb.append("</init-param>");
206 sb.append("<load-on-startup>0</load-on-startup>");
207 sb.append("</servlet>");
208
209 sb.append("<servlet-mapping>");
210 sb.append("<servlet-name>");
211 sb.append(portletName);
212 sb.append("</servlet-name>");
213 sb.append("<url-pattern>/");
214 sb.append(portletName);
215 sb.append("/*</url-pattern>");
216 sb.append("</servlet-mapping>");
217 }
218
219
221 doc = SAXReaderUtil.read(webXML);
222
223 root = doc.getRootElement();
224
225
227 itr1 = root.elements("servlet").iterator();
228
229 while (itr1.hasNext()) {
230 Element servlet = itr1.next();
231
232 String icon = servlet.elementText("icon");
233 String servletName = servlet.elementText("servlet-name");
234 String displayName = servlet.elementText("display-name");
235 String description = servlet.elementText("description");
236 String servletClass = servlet.elementText("servlet-class");
237 List<Element> initParams = servlet.elements("init-param");
238 String loadOnStartup = servlet.elementText("load-on-startup");
239 String runAs = servlet.elementText("run-as");
240 List<Element> securityRoleRefs = servlet.elements(
241 "security-role-ref");
242
243 if ((servletClass != null) &&
244 (servletClass.equals(
245 "com.liferay.portal.servlet.SharedServletWrapper"))) {
246
247 sb.append("<servlet>");
248
249 if (icon != null) {
250 sb.append("<icon>");
251 sb.append(icon);
252 sb.append("</icon>");
253 }
254
255 if (servletName != null) {
256 sb.append("<servlet-name>");
257 sb.append(servletName);
258 sb.append("</servlet-name>");
259 }
260
261 if (displayName != null) {
262 sb.append("<display-name>");
263 sb.append(displayName);
264 sb.append("</display-name>");
265 }
266
267 if (description != null) {
268 sb.append("<description>");
269 sb.append(description);
270 sb.append("</description>");
271 }
272
273 Iterator<Element> itr2 = initParams.iterator();
274
275 while (itr2.hasNext()) {
276 Element initParam = itr2.next();
277
278 String paramName = initParam.elementText("param-name");
279 String paramValue = initParam.elementText("param-value");
280
281 if ((paramName != null) &&
282 (paramName.equals("servlet-class"))) {
283
284 sb.append("<servlet-class>");
285 sb.append(paramValue);
286 sb.append("</servlet-class>");
287 }
288 }
289
290 itr2 = initParams.iterator();
291
292 while (itr2.hasNext()) {
293 Element initParam = itr2.next();
294
295 String paramName = initParam.elementText("param-name");
296 String paramValue = initParam.elementText("param-value");
297 String paramDesc = initParam.elementText("description");
298
299 if ((paramName != null) &&
300 (!paramName.equals("servlet-class"))) {
301
302 sb.append("<init-param>");
303 sb.append("<param-name>");
304 sb.append(paramName);
305 sb.append("</param-name>");
306
307 if (paramValue != null) {
308 sb.append("<param-value>");
309 sb.append(paramValue);
310 sb.append("</param-value>");
311 }
312
313 if (paramDesc != null) {
314 sb.append("<description>");
315 sb.append(paramDesc);
316 sb.append("</description>");
317 }
318
319 sb.append("</init-param>");
320 }
321 }
322
323 if (loadOnStartup != null) {
324 sb.append("<load-on-startup>");
325 sb.append(loadOnStartup);
326 sb.append("</load-on-startup>");
327 }
328
329 if (runAs != null) {
330 sb.append("<run-as>");
331 sb.append(runAs);
332 sb.append("</run-as>");
333 }
334
335 itr2 = securityRoleRefs.iterator();
336
337 while (itr2.hasNext()) {
338 Element roleRef = itr2.next();
339
340 String roleDesc = roleRef.elementText("description");
341 String roleName = roleRef.elementText("role-name");
342 String roleLink = roleRef.elementText("role-link");
343
344 sb.append("<security-role-ref>");
345
346 if (roleDesc != null) {
347 sb.append("<description>");
348 sb.append(roleDesc);
349 sb.append("</description>");
350 }
351
352 if (roleName != null) {
353 sb.append("<role-name>");
354 sb.append(roleName);
355 sb.append("</role-name>");
356 }
357
358 if (roleLink != null) {
359 sb.append("<role-link>");
360 sb.append(roleLink);
361 sb.append("</role-link>");
362 }
363
364 sb.append("</security-role-ref>");
365 }
366
367 sb.append("</servlet>");
368 }
369 }
370
371 return sb.toString();
372 }
373
374 protected void processPluginPackageProperties(
375 File srcFile, String displayName, PluginPackage pluginPackage)
376 throws Exception {
377
378 if (pluginPackage == null) {
379 return;
380 }
381
382 Properties props = getPluginPackageProperties(srcFile);
383
384 if ((props == null) || (props.size() == 0)) {
385 return;
386 }
387
388 String moduleGroupId = pluginPackage.getGroupId();
389 String moduleArtifactId = pluginPackage.getArtifactId();
390 String moduleVersion = pluginPackage.getVersion();
391
392 String pluginName = pluginPackage.getName();
393 String pluginType = pluginPackage.getTypes().get(0);
394 String pluginTypeName = TextFormatter.format(
395 pluginType, TextFormatter.J);
396
397 if (!pluginType.equals(Plugin.TYPE_PORTLET)) {
398 return;
399 }
400
401 String tags = getPluginPackageTagsXml(pluginPackage.getTags());
402 String shortDescription = pluginPackage.getShortDescription();
403 String longDescription = pluginPackage.getLongDescription();
404 String changeLog = pluginPackage.getChangeLog();
405 String pageURL = pluginPackage.getPageURL();
406 String author = pluginPackage.getAuthor();
407 String licenses = getPluginPackageLicensesXml(
408 pluginPackage.getLicenses());
409 String liferayVersions = getPluginPackageLiferayVersionsXml(
410 pluginPackage.getLiferayVersions());
411
412 Map<String, String> filterMap = new HashMap<String, String>();
413
414 filterMap.put("module_group_id", moduleGroupId);
415 filterMap.put("module_artifact_id", moduleArtifactId);
416 filterMap.put("module_version", moduleVersion);
417
418 filterMap.put("plugin_name", pluginName);
419 filterMap.put("plugin_type", pluginType);
420 filterMap.put("plugin_type_name", pluginTypeName);
421
422 filterMap.put("tags", tags);
423 filterMap.put("short_description", shortDescription);
424 filterMap.put("long_description", longDescription);
425 filterMap.put("change_log", changeLog);
426 filterMap.put("page_url", pageURL);
427 filterMap.put("author", author);
428 filterMap.put("licenses", licenses);
429 filterMap.put("liferay_versions", liferayVersions);
430
431 copyDependencyXml(
432 "liferay-plugin-package.xml", srcFile + "/WEB-INF", filterMap,
433 true);
434 }
435
436 protected void setupJSF(File facesXML, File portletXML) throws Exception {
437 _myFacesPortlet = false;
438 _sunFacesPortlet = false;
439
440 if (!facesXML.exists()) {
441 return;
442 }
443
444
446 Document doc = SAXReaderUtil.read(portletXML, true);
447
448 Element root = doc.getRootElement();
449
450 List<Element> elements = root.elements("portlet");
451
452 Iterator<Element> itr = elements.iterator();
453
454 while (itr.hasNext()) {
455 Element portlet = itr.next();
456
457 String portletClass = portlet.elementText("portlet-class");
458
459 if (portletClass.equals(JSF_MYFACES)) {
460 _myFacesPortlet = true;
461
462 break;
463 }
464 else if (portletClass.equals(JSF_SUN)) {
465 _sunFacesPortlet = true;
466
467 break;
468 }
469 }
470
471
473 doc = SAXReaderUtil.read(facesXML, true);
474
475 root = doc.getRootElement();
476
477 Element factoryEl = root.element("factory");
478
479 Element renderKitFactoryEl = null;
480 Element facesContextFactoryEl = null;
481
482 if (factoryEl == null) {
483 factoryEl = root.addElement("factory");
484 }
485
486 renderKitFactoryEl = factoryEl.element("render-kit-factory");
487 facesContextFactoryEl = factoryEl.element("faces-context-factory");
488
489 if ((appServerType.equals("orion") && (_sunFacesPortlet) &&
490 (renderKitFactoryEl == null))) {
491
492 renderKitFactoryEl = factoryEl.addElement("render-kit-factory");
493
494 renderKitFactoryEl.addText(LIFERAY_RENDER_KIT_FACTORY);
495 }
496 else if (_myFacesPortlet && (facesContextFactoryEl == null)) {
497 facesContextFactoryEl =
498 factoryEl.addElement("faces-context-factory");
499
500 facesContextFactoryEl.addText(MYFACES_CONTEXT_FACTORY);
501 }
502
503 if (!appServerType.equals("orion") && (_sunFacesPortlet)) {
504 factoryEl.detach();
505 }
506
507 XMLMerger merger = new XMLMerger(new FacesXMLDescriptor());
508
509 DocumentImpl docImpl = (DocumentImpl)doc;
510
511 merger.organizeXML(docImpl.getWrappedDocument());
512
513 FileUtil.write(facesXML, doc.formattedString(), true);
514 }
515
516 protected void updateDeployDirectory(File srcFile) throws Exception {
517 try {
518 if (!PrefsPropsUtil.getBoolean(
519 PropsKeys.AUTO_DEPLOY_CUSTOM_PORTLET_XML,
520 PropsValues.AUTO_DEPLOY_CUSTOM_PORTLET_XML)) {
521
522 return;
523 }
524 }
525 catch (Exception e) {
526
527
531 if (!PropsValues.AUTO_DEPLOY_CUSTOM_PORTLET_XML) {
532 return;
533 }
534 }
535
536 File portletXML = new File(
537 srcFile + "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_STANDARD);
538
539 if (portletXML.exists()) {
540 File portletCustomXML = new File(
541 srcFile + "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM);
542
543 if (portletCustomXML.exists()) {
544 portletCustomXML.delete();
545 }
546
547 portletXML.renameTo(portletCustomXML);
548 }
549 }
550
551 private boolean _myFacesPortlet;
552 private boolean _sunFacesPortlet;
553
554 }