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