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