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