View Javadoc

1   /*
2    * Copyright 2003,2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.pluto.portalImpl;
18  
19  import java.io.BufferedReader;
20  import java.io.File;
21  import java.io.FileInputStream;
22  import java.io.FileOutputStream;
23  import java.io.FileWriter;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.InputStreamReader;
27  import java.io.RandomAccessFile;
28  import java.io.Reader;
29  import java.io.StreamTokenizer;
30  import java.util.Collection;
31  import java.util.Enumeration;
32  import java.util.Iterator;
33  import java.util.Locale;
34  import java.util.StringTokenizer;
35  import java.util.Vector;
36  import java.util.jar.JarEntry;
37  import java.util.jar.JarFile;
38  
39  import org.apache.pluto.om.common.Parameter;
40  import org.apache.pluto.om.common.ParameterCtrl;
41  import org.apache.pluto.om.common.ParameterSet;
42  import org.apache.pluto.om.common.ParameterSetCtrl;
43  import org.apache.pluto.om.common.SecurityRoleRef;
44  import org.apache.pluto.om.common.SecurityRoleRefSet;
45  import org.apache.pluto.om.common.SecurityRoleRefSetCtrl;
46  import org.apache.pluto.om.common.SecurityRoleSet;
47  import org.apache.pluto.om.portlet.PortletDefinition;
48  import org.apache.pluto.om.servlet.ServletDefinition;
49  import org.apache.pluto.om.servlet.ServletDefinitionCtrl;
50  import org.apache.pluto.om.servlet.ServletDefinitionListCtrl;
51  import org.apache.pluto.portalImpl.om.common.impl.DescriptionImpl;
52  import org.apache.pluto.portalImpl.om.common.impl.DescriptionSetImpl;
53  import org.apache.pluto.portalImpl.om.common.impl.DisplayNameImpl;
54  import org.apache.pluto.portalImpl.om.common.impl.DisplayNameSetImpl;
55  import org.apache.pluto.portalImpl.om.portlet.impl.PortletApplicationDefinitionImpl;
56  import org.apache.pluto.portalImpl.om.servlet.impl.ServletDefinitionImpl;
57  import org.apache.pluto.portalImpl.om.servlet.impl.ServletMappingImpl;
58  import org.apache.pluto.portalImpl.om.servlet.impl.WebApplicationDefinitionImpl;
59  import org.apache.pluto.portalImpl.xml.Constants;
60  import org.apache.pluto.portalImpl.xml.XmlParser;
61  import org.apache.pluto.portlet.admin.PlutoAdminException;
62  import org.apache.xml.serialize.OutputFormat;
63  import org.apache.xml.serialize.XMLSerializer;
64  import org.exolab.castor.mapping.Mapping;
65  import org.exolab.castor.xml.Marshaller;
66  import org.exolab.castor.xml.Unmarshaller;
67  
68  /***
69   * @deprecated this deployment utility has been deprecated in
70   * favor of the one provided with the deploy subproject.
71   *
72   * @see org.apache.pluto.driver.deploy.CLI
73   *
74   */
75  public class Deploy {
76  
77      private static boolean debug = false;
78      private static String dirDelim = System.getProperty("file.separator");
79      private static String webInfDir = dirDelim + "WEB-INF" + dirDelim;
80      private static String webAppsDir;
81      private static String portalImplWebDir;
82      private static String plutoHome;
83  
84      public static void deployArchive(String webAppsDir, String warFile)
85          throws IOException {
86          String warFileName = warFile;
87          if (warFileName.indexOf("/") != -1)
88              warFileName =
89                  warFileName.substring(warFileName.lastIndexOf("/") + 1);
90          if (warFileName.indexOf(dirDelim) != -1)
91              warFileName =
92                  warFileName.substring(warFileName.lastIndexOf(dirDelim) + 1);
93          if (warFileName.endsWith(".war"))
94              warFileName =
95                  warFileName.substring(0, warFileName.lastIndexOf("."));
96  
97          System.out.println("deploying '" + warFileName + "' ...");
98  
99          String destination = webAppsDir + warFileName;
100 
101         JarFile jarFile = new JarFile(warFile);
102         Enumeration files = jarFile.entries();
103         while (files.hasMoreElements()) {
104             JarEntry entry = (JarEntry) files.nextElement();
105 
106 
107             /* Check for use of '/WEB-INF/tld/portlet.tld' instead of 'http://java.sun.com/portlet'" target="alexandria_uri">http://java.sun.com/portlet' in taglib declaration*/
108             String fileName = entry.getName();
109             if( !entry.isDirectory() && entry.getName().endsWith(".jsp")) {
110         		InputStream is = jarFile.getInputStream(entry);
111         		Reader r = new BufferedReader(new InputStreamReader(is));
112         		StreamTokenizer st = new StreamTokenizer(r);
113         		st.quoteChar('\'');
114         		st.quoteChar('"');
115         		while(st.nextToken()!=StreamTokenizer.TT_EOF) {
116         			if(st.ttype=='\'' || st.ttype=='"'){
117         				String sval = st.sval;
118         				String sqc = Character.toString((char)st.ttype);
119         				if(sval.equals("/WEB-INF/tld/portlet.tld")){
120         					System.out.println("Warning: " + sqc+st.sval+sqc + " has been found in file " + fileName + ". Use instead " +sqc+"http://java.sun.com/portlet"+sqc+" with your portlet taglib declaration!\n");
121         					break;
122         				}
123         			}
124         		}
125          	}
126 
127             File file = new File(destination, fileName);
128             File dirF = new File(file.getParent());
129             dirF.mkdirs();
130             if (entry.isDirectory()) {
131                 file.mkdirs();
132             } else {
133                 byte[] buffer = new byte[1024];
134                 int length = 0;
135                 InputStream fis = jarFile.getInputStream(entry);
136                 FileOutputStream fos = new FileOutputStream(file);
137                 while ((length = fis.read(buffer)) >= 0) {
138                     fos.write(buffer, 0, length);
139                 }
140                 fos.close();
141             }
142 
143         }
144 
145         System.out.println("finished!");
146     }
147 
148     public static void prepareWebArchive(String webAppsDir, String warFile)
149         throws Exception, IOException {
150         String webModule = warFile;
151         if (webModule.indexOf("/") != -1)
152             webModule = webModule.substring(webModule.lastIndexOf("/") + 1);
153         if (webModule.indexOf(dirDelim) != -1)
154             webModule =
155                 webModule.substring(webModule.lastIndexOf(dirDelim) + 1);
156         if (webModule.endsWith(".war"))
157             webModule = webModule.substring(0, webModule.lastIndexOf("."));
158 
159         System.out.println("prepare web archive '" + webModule + "' ...");
160 
161         Mapping mappingPortletXml = null;
162         Mapping mappingWebXml = null;
163 
164         // get portlet xml mapping file
165         String _portlet_mapping =
166             webAppsDir + portalImplWebDir + "WEB-INF" + dirDelim + "data" + dirDelim + "xml" +dirDelim + "portletdefinitionmapping.xml";
167         mappingPortletXml = new Mapping();
168         try {
169             mappingPortletXml.loadMapping(_portlet_mapping);
170         } catch (Exception e) {
171             System.out.println("CASTOR-Exception: " + e);
172             throw new IOException(
173             "Failed to load mapping file " + _portlet_mapping + ". Cause of mapping error: " + e.getMessage());
174         }
175 
176         File portletXml =
177             new File(webAppsDir + webModule + webInfDir + "portlet.xml");
178 
179         // get web xml mapping file
180         String _web_mapping =
181             webAppsDir
182                 + portalImplWebDir
183                 + "WEB-INF" + dirDelim + "data" + dirDelim + "xml" + dirDelim + "servletdefinitionmapping.xml";
184         mappingWebXml = new Mapping();
185         try {
186             mappingWebXml.loadMapping(_web_mapping);
187         } catch (Exception e) {
188             throw new IOException(
189                 "Failed to load mapping file " + _web_mapping + ". Cause of mapping error: " + e.getMessage());
190         }
191 
192         File webXml = new File(webAppsDir + webModule + webInfDir + "web.xml");
193 
194         try {
195             org.w3c.dom.Document portletDocument =
196                 XmlParser.parsePortletXml(new FileInputStream(portletXml));
197 
198             Unmarshaller unmarshaller = new Unmarshaller(mappingPortletXml);
199 
200             // modified by YCLI: START :: to ignore extra elements and attributes
201             unmarshaller.setIgnoreExtraElements(true);
202             unmarshaller.setIgnoreExtraAttributes(true);
203             // modified by YCLI: END
204 
205             PortletApplicationDefinitionImpl portletApp =
206                 (PortletApplicationDefinitionImpl) unmarshaller.unmarshal(
207                     portletDocument);
208 
209             // refill structure with necessary information
210             Vector structure = new Vector();
211             structure.add(webModule);
212             structure.add(null);
213             structure.add(null);
214             portletApp.preBuild(structure);
215 
216             if (debug) {
217                 System.out.println(portletApp);
218             }
219 
220             // now generate web part
221 
222             WebApplicationDefinitionImpl webApp = null;
223 
224             if (webXml.exists()) {
225                 org.w3c.dom.Document webDocument =
226                     XmlParser.parseWebXml(new FileInputStream(webXml));
227 
228                 Unmarshaller unmarshallerWeb = new Unmarshaller(mappingWebXml);
229 
230                 // modified by YCLI: START :: to ignore extra elements and attributes
231                 unmarshallerWeb.setIgnoreExtraElements(true);
232                 unmarshallerWeb.setIgnoreExtraAttributes(true);
233                 // modified by YCLI: END
234 
235                 webApp =
236                     (WebApplicationDefinitionImpl) unmarshallerWeb.unmarshal(
237                         webDocument);
238             } else {
239                 webApp = new WebApplicationDefinitionImpl();
240                 DisplayNameImpl dispName = new DisplayNameImpl();
241                 dispName.setDisplayName(webModule);
242                 dispName.setLocale(Locale.ENGLISH);
243                 DisplayNameSetImpl dispSet = new DisplayNameSetImpl();
244                 dispSet.add(dispName);
245                 webApp.setDisplayNames(dispSet);
246                 DescriptionImpl desc = new DescriptionImpl();
247                 desc.setDescription("Automated generated Application Wrapper");
248                 desc.setLocale(Locale.ENGLISH);
249                 DescriptionSetImpl descSet = new DescriptionSetImpl();
250                 descSet.add(desc);
251                 webApp.setDescriptions(descSet);
252             }
253 
254             org.apache.pluto.om.ControllerFactory controllerFactory =
255                 new org.apache.pluto.portalImpl.om.ControllerFactoryImpl();
256 
257             ServletDefinitionListCtrl servletDefinitionSetCtrl =
258                 (ServletDefinitionListCtrl) controllerFactory.get(
259                     webApp.getServletDefinitionList());
260             Collection servletMappings = webApp.getServletMappings();
261 
262             Iterator portlets =
263                 portletApp.getPortletDefinitionList().iterator();
264             while (portlets.hasNext()) {
265 
266                 PortletDefinition portlet = (PortletDefinition) portlets.next();
267 
268                 // check if already exists
269                 ServletDefinition servlet =
270                     webApp.getServletDefinitionList().get(portlet.getName());
271                 if (servlet != null) {
272                     if (!servlet
273                         .getServletClass()
274                         .equals("org.apache.pluto.core.PortletServlet")) {
275                         System.out.println(
276                             "Note: Replaced already existing the servlet with the name '"
277                                 + portlet.getName()
278                                 + "' with the wrapper servlet.");
279                     }
280                     ServletDefinitionCtrl _servletCtrl =
281                         (ServletDefinitionCtrl) controllerFactory.get(servlet);
282                     _servletCtrl.setServletClass(
283                         "org.apache.pluto.core.PortletServlet");
284                 } else {
285                     servlet =
286                         servletDefinitionSetCtrl.add(
287                             portlet.getName(),
288                             "org.apache.pluto.core.PortletServlet");
289                 }
290 
291                 ServletDefinitionCtrl servletCtrl =
292                     (ServletDefinitionCtrl) controllerFactory.get(servlet);
293 
294                 DisplayNameImpl dispName = new DisplayNameImpl();
295                 dispName.setDisplayName(portlet.getName() + " Wrapper");
296                 dispName.setLocale(Locale.ENGLISH);
297                 DisplayNameSetImpl dispSet = new DisplayNameSetImpl();
298                 dispSet.add(dispName);
299                 servletCtrl.setDisplayNames(dispSet);
300                 DescriptionImpl desc = new DescriptionImpl();
301                 desc.setDescription("Automated generated Portlet Wrapper");
302                 desc.setLocale(Locale.ENGLISH);
303                 DescriptionSetImpl descSet = new DescriptionSetImpl();
304                 descSet.add(desc);
305                 servletCtrl.setDescriptions(descSet);
306                 ParameterSet parameters = servlet.getInitParameterSet();
307 
308                 ParameterSetCtrl parameterSetCtrl =
309                     (ParameterSetCtrl) controllerFactory.get(parameters);
310 
311                 Parameter parameter1 = parameters.get("portlet-class");
312                 if (parameter1 == null) {
313                     parameterSetCtrl.add(
314                         "portlet-class",
315                         portlet.getClassName());
316                 } else {
317                     ParameterCtrl parameterCtrl =
318                         (ParameterCtrl) controllerFactory.get(parameter1);
319                     parameterCtrl.setValue(portlet.getClassName());
320 
321                 }
322                 Parameter parameter2 = parameters.get("portlet-guid");
323                 if (parameter2 == null) {
324                     parameterSetCtrl.add(
325                         "portlet-guid",
326                         portlet.getId().toString());
327                 } else {
328                     ParameterCtrl parameterCtrl =
329                         (ParameterCtrl) controllerFactory.get(parameter2);
330                     parameterCtrl.setValue(portlet.getId().toString());
331 
332                 }
333 
334                 boolean found = false;
335                 Iterator mappings = servletMappings.iterator();
336                 while (mappings.hasNext()) {
337                     ServletMappingImpl servletMapping =
338                         (ServletMappingImpl) mappings.next();
339                     if (servletMapping
340                         .getServletName()
341                         .equals(portlet.getName())) {
342                         found = true;
343                         servletMapping.setUrlPattern(
344                             "/" + portlet.getName().replace(' ', '_') + "/*");
345                     }
346                 }
347                 if (!found) {
348                     ServletMappingImpl servletMapping =
349                         new ServletMappingImpl();
350                     servletMapping.setServletName(portlet.getName());
351                     servletMapping.setUrlPattern(
352                         "/" + portlet.getName().replace(' ', '_') + "/*");
353                     servletMappings.add(servletMapping);
354                 }
355 
356                 SecurityRoleRefSet servletSecurityRoleRefs =
357                     ((ServletDefinitionImpl)servlet).getInitSecurityRoleRefSet();
358 
359                 SecurityRoleRefSetCtrl servletSecurityRoleRefSetCtrl =
360                     (SecurityRoleRefSetCtrl) controllerFactory.get(
361                         servletSecurityRoleRefs);
362 
363                 SecurityRoleSet webAppSecurityRoles = webApp.getSecurityRoles();
364 
365                 SecurityRoleRefSet portletSecurityRoleRefs =
366                     portlet.getInitSecurityRoleRefSet();
367 
368                 Iterator p = portletSecurityRoleRefs.iterator();
369 
370                 while (p.hasNext()) {
371                     SecurityRoleRef portletSecurityRoleRef =
372                         (SecurityRoleRef) p.next();
373 
374                     if (	portletSecurityRoleRef.getRoleLink()== null
375                         &&
376                             webAppSecurityRoles.get(portletSecurityRoleRef.getRoleName())==null
377                     ){
378                         System.out.println(
379                             "Note: The web application has no security role defined which matches the role name \""
380                                 + portletSecurityRoleRef.getRoleName()
381                                 + "\" of the security-role-ref element defined for the wrapper-servlet with the name '"
382                                 + portlet.getName()
383                                 + "'.");
384                         break;
385                     }
386                     SecurityRoleRef servletSecurityRoleRef =
387                         servletSecurityRoleRefs.get(
388                             portletSecurityRoleRef.getRoleName());
389                     if (null != servletSecurityRoleRef) {
390                         System.out.println(
391                             "Note: Replaced already existing element of type <security-role-ref> with value \""
392                                 + portletSecurityRoleRef.getRoleName()
393                                 + "\" for subelement of type <role-name> for the wrapper-servlet with the name '"
394                                 + portlet.getName()
395                                 + "'.");
396                         servletSecurityRoleRefSetCtrl.remove(
397                             servletSecurityRoleRef);
398                     }
399                     servletSecurityRoleRefSetCtrl.add(portletSecurityRoleRef);
400                 }
401 
402             }
403 
404             if (debug) {
405                 System.out.println(webApp);
406             }
407 
408             OutputFormat of = new OutputFormat();
409             of.setIndenting(true);
410             of.setIndent(4); // 2-space indention
411             of.setLineWidth(16384);
412             // As large as needed to prevent linebreaks in text nodes
413             of.setDoctype(
414                 Constants.WEB_PORTLET_PUBLIC_ID,
415                 Constants.WEB_PORTLET_DTD);
416 
417             FileWriter writer =
418                 new FileWriter(webAppsDir + webModule +
419                                                System.getProperty("file.separator") + "WEB-INF"+
420                                                System.getProperty("file.separator") + "web.xml");
421             XMLSerializer serializer = new XMLSerializer(writer, of);
422             try {
423             Marshaller marshaller =
424                 new Marshaller(serializer.asDocumentHandler());
425             marshaller.setMapping(mappingWebXml);
426             marshaller.marshal(webApp);
427             } catch (Exception e) {
428                 writer.close();
429                 e.printStackTrace(System.out);
430                 throw new PlutoAdminException("Error found in Deploy.prepareWebArchive()", e);
431             }
432             // REMOVED copy of  tld b/c it's now included in the container distribution.
433             //String strTo = dirDelim + "WEB-INF" + dirDelim + "tld" + dirDelim + "portlet.tld";
434             //String strFrom = plutoHome + "portal" + dirDelim + "src" +
435             //    dirDelim + "webapp" + strTo;
436 
437             //copy(strFrom, webAppsDir + webModule + strTo);
438         } catch (Exception e) {
439 
440             e.printStackTrace(System.out);
441             throw new PlutoAdminException("Error found in Deploy.prepareWebArchive()", e);
442         }
443 
444         System.out.println("finished!");
445     }
446 
447     public static void copy(String from, String to) throws IOException {
448         File f = new File(to);
449         f.getParentFile().mkdirs();
450 
451         byte[] buffer = new byte[1024];
452         int length = 0;
453         InputStream fis = new FileInputStream(from);
454         FileOutputStream fos = new FileOutputStream(f);
455 
456         while ((length = fis.read(buffer)) >= 0) {
457             fos.write(buffer, 0, length);
458         }
459         fos.close();
460     }
461 
462     public static void main(String args[]) {
463         String warFile;
464 
465 
466         if (args.length < 4) {
467             System.out.println(
468                 "No argument specified. This command must be issued as:");
469             System.out.println(
470                 "deploy <TOMCAT-webapps-directory> <TOMCAT-pluto-webmodule-name> <web-archive> <pluto-home-dir> [-debug] [-addToEntityReg <app-id> [<portlet-id>:<portlet-name>]+]");
471             return;
472         }
473 
474         if (args.length > 4) {
475             if ((args[4].equals("-debug")) || (args[4].equals("/debug"))) {
476                 debug = true;
477             }
478         }
479 
480         if(debug) {
481             for(int i=0; i<args.length;i++) {
482                 System.out.println( "args["+ i +"]:" + args[i]);
483             }
484         }
485 
486         webAppsDir = args[0];
487         if (!webAppsDir.endsWith(dirDelim))
488             webAppsDir += dirDelim;
489 
490         portalImplWebDir = args[1];
491         if (!portalImplWebDir.endsWith(dirDelim))
492             portalImplWebDir += dirDelim;
493 
494         warFile = args[2];
495 
496         plutoHome = args[3];
497         if (!plutoHome.endsWith(dirDelim))
498             plutoHome += dirDelim;
499 
500         if (args.length > 4) {
501             if ((args[4].equals("-debug")) || (args[4].equals("/debug"))) {
502                 debug = true;
503             }
504             if (
505                   (args[4].equals("-addToEntityReg"))
506                || (  (args.length>5)
507                   && (args[5].equals("-addToEntityReg"))
508                   )
509             ) {
510                 // parameters: app-id   portlet application id; must be unique in portletentityregistry.xml
511                 //             portlet-id   portlet id; must be unique inside the portlet application
512                 //             portlet-name the name of the portlet in portlet.xml
513                 addToEntityReg(args);
514             }
515         }
516 
517         try {
518             deployArchive(webAppsDir, warFile);
519 
520 //            prepareWebArchive(webAppsDir, warFile);
521         } catch (PlutoAdminException e) {
522             throw e;
523         } catch (Exception e) {
524             e.printStackTrace(System.out);
525             throw new PlutoAdminException("Error found in Deploy.main()", e);
526         }
527 
528     }
529 
530     static private void addToEntityReg(String[] args) {
531         File portletAppFile = new File(args[2]);
532         String portletAppFileName = portletAppFile.getName();
533         String portletApp =
534             portletAppFileName.substring(0,	portletAppFileName.lastIndexOf(".war"));
535         int o = (args[4].equals("-addToEntityReg") ? 5 : 6);
536         String appId = args[o++];
537         try {
538             String entityMapping = webAppsDir + portalImplWebDir
539   					               + "WEB-INF/data/portletentityregistry.xml";
540             File file = new File(entityMapping);
541             RandomAccessFile ras = new RandomAccessFile(file, "rw");
542             long length = ras.length();
543             byte[] contentByte = new byte[(int) length];
544             ras.read(contentByte);
545             String contentString = new String(contentByte);
546             long pos = contentString.lastIndexOf("</portlet-entity-registry>");
547             ras.seek(pos);
548             ras.writeBytes("    <application id=\"" + appId + "\">\r\n");
549             ras.writeBytes("        <definition-id>" + portletApp + "</definition-id>\r\n");
550 
551             StringTokenizer tokenizer;
552             for (int i = o; i < args.length; ++i) {
553                 tokenizer = new StringTokenizer(args[i], ":");
554                 String portletId = tokenizer.nextToken();
555                 String portletName = tokenizer.nextToken();
556                 ras.writeBytes("        <portlet id=\"" + portletId + "\">\r\n");
557                 ras.writeBytes("            <definition-id>" + portletApp
558                                + "." + portletName + "</definition-id>\r\n");
559                 ras.writeBytes("        </portlet>\r\n");
560             }
561             ras.writeBytes("    </application>\r\n");
562             ras.writeBytes("</portlet-entity-registry>\r\n");
563             ras.close();
564 
565         } catch (Exception e) {
566             e.printStackTrace(System.out);
567             throw new PlutoAdminException("Error found in Deploy.addToEntityReg()", e);
568         }
569     }
570 
571 }