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