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