View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugin.eclipse.writers.rad;
20  
21  import java.io.File;
22  import java.io.FileInputStream;
23  import java.io.FileNotFoundException;
24  import java.io.FileOutputStream;
25  import java.io.IOException;
26  import java.io.InputStreamReader;
27  import java.io.OutputStreamWriter;
28  import java.io.Reader;
29  import java.io.Writer;
30  import java.util.Arrays;
31  import java.util.Comparator;
32  
33  import org.apache.maven.artifact.repository.ArtifactRepository;
34  import org.apache.maven.plugin.MojoExecutionException;
35  import org.apache.maven.plugin.eclipse.Constants;
36  import org.apache.maven.plugin.eclipse.EclipseSourceDir;
37  import org.apache.maven.plugin.eclipse.Messages;
38  import org.apache.maven.plugin.eclipse.writers.AbstractEclipseWriter;
39  import org.apache.maven.plugin.eclipse.writers.wtp.AbstractWtpResourceWriter;
40  import org.codehaus.plexus.util.IOUtil;
41  import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
42  import org.codehaus.plexus.util.xml.XMLWriter;
43  import org.codehaus.plexus.util.xml.Xpp3Dom;
44  import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
45  import org.codehaus.plexus.util.xml.Xpp3DomWriter;
46  
47  /**
48   * Adapts the .classpath file for RAD6 for now write hardcoded: target/websphere/classes future releases could make this
49   * varriable.
50   * 
51   * @author <a href="mailto:nir@cfc.at">Richard van Nieuwenhoven </a>
52   */
53  public class RadEjbClasspathWriter
54      extends AbstractEclipseWriter
55  {
56  
57      private static final String CLASSPATH = "classpath";
58  
59      private static final String CLASSPATH_FILE = ".classpath";
60  
61      private static final String CLASSPATHENTRY = "classpathentry";
62  
63      private static final String CON = "con";
64  
65      private static final String KIND = "kind";
66  
67      private static final String LIB = "lib";
68  
69      private static final String OUTPUT = "output";
70  
71      private static final String PATH = "path";
72  
73      private static final String SRC = "src";
74  
75      private static final String TARGET_WEBSPHERE_CLASSES = "target/websphere/generated-classes";
76  
77      private static final String VAR = "var";
78  
79      private static final String WEBSPHERE6CONTAIGNER =
80          "com.ibm.wtp.server.java.core.container/com.ibm.ws.ast.st.runtime.core.runtimeTarget.v60/was.base.v6";
81  
82      /**
83       * write the .classpath file to the project root directory.
84       * 
85       * @see AbstractWtpResourceWriter#write(EclipseSourceDir[], ArtifactRepository, File)
86       * @param sourceDirs all eclipse source directorys
87       * @param localRepository the local reposetory
88       * @param buildOutputDirectory build output directory (target)
89       * @throws MojoExecutionException when writing the config files was not possible
90       */
91      public void write()
92          throws MojoExecutionException
93      {
94          String packaging = config.getPackaging();
95          if ( Constants.PROJECT_PACKAGING_EJB.equalsIgnoreCase( packaging ) )
96          {
97              new File( config.getEclipseProjectDirectory(), TARGET_WEBSPHERE_CLASSES ).mkdirs();
98              File classpathFile = new File( config.getEclipseProjectDirectory(), CLASSPATH_FILE );
99  
100             if ( !classpathFile.exists() )
101             {
102                 return;
103             }
104             Xpp3Dom classpath = readXMLFile( classpathFile );
105             Xpp3Dom[] children = classpath.getChildren();
106             for ( int index = 0; index < children.length; index++ )
107             {
108                 if ( LIB.equals( children[index].getAttribute( KIND ) ) &&
109                     TARGET_WEBSPHERE_CLASSES.equals( children[index].getAttribute( "path" ) ) )
110                 {
111                     return; // nothing to do!
112                 }
113             }
114 
115             Xpp3Dom newEntry = new Xpp3Dom( CLASSPATHENTRY );
116             newEntry.setAttribute( KIND, LIB );
117             newEntry.setAttribute( PATH, TARGET_WEBSPHERE_CLASSES );
118             classpath.addChild( newEntry );
119 
120             newEntry = new Xpp3Dom( CLASSPATHENTRY );
121             newEntry.setAttribute( KIND, CON );
122             newEntry.setAttribute( PATH, WEBSPHERE6CONTAIGNER );
123             classpath.addChild( newEntry );
124 
125             children = classpath.getChildren();
126             for ( int index = children.length - 1; index >= 0; index-- )
127             {
128                 if ( children[index].getValue() == null )
129                 {
130                     children[index].setValue( "" );
131                 }
132             }
133 
134             removeDupicateWAS6Libs( classpath );
135             classpath = orderClasspath( classpath );
136 
137             Writer w;
138             try
139             {
140                 w = new OutputStreamWriter( new FileOutputStream( classpathFile ), "UTF-8" );
141             }
142             catch ( IOException ex )
143             {
144                 throw new MojoExecutionException( Messages.getString( "EclipsePlugin.erroropeningfile" ), ex ); //$NON-NLS-1$
145             }
146             XMLWriter writer = new PrettyPrintXMLWriter( w, "UTF-8", null );
147             Xpp3DomWriter.write( writer, classpath );
148             IOUtil.close( w );
149         }
150     }
151 
152     /**
153      * determinate of witch type this classpath entry is. this is used for sorting them.
154      * 
155      * @param classpathentry the classpath entry to sort
156      * @return an integer identifieing the type
157      * @see RadEjbClasspathWriter#orderClasspath(Xpp3Dom)
158      */
159     private int detectClasspathEntryType( Xpp3Dom classpathentry )
160     {
161         String kind = classpathentry.getAttribute( KIND );
162         String path = classpathentry.getAttribute( PATH );
163 
164         if ( kind == null || path == null )
165         {
166             return 6;
167         }
168 
169         boolean absolutePath = path.startsWith( "\\" ) || path.startsWith( "/" );
170         boolean windowsAbsolutePath = path.indexOf( ':' ) >= 0;
171         boolean anyAbsolutePath = absolutePath || windowsAbsolutePath;
172 
173         if ( kind.equals( SRC ) && !absolutePath )
174         {
175             return 1;
176         }
177         else if ( kind.equals( LIB ) && !anyAbsolutePath )
178         {
179             return 2;
180         }
181         else if ( kind.equals( SRC ) )
182         {
183             return 3;
184         }
185         else if ( kind.equals( VAR ) )
186         {
187             return 4;
188         }
189         else if ( kind.equals( LIB ) )
190         {
191             return 5;
192         }
193         else if ( kind.equals( OUTPUT ) )
194         {
195             return 7;
196         }
197         else
198         {
199             return 6;
200         }
201     }
202 
203     /**
204      * Order of classpath this is nessesary for the ejb's the generated classes are elsewise not found. 1 - kind=src
205      * ohne starting '/' oder '\' 2 - kind=lib kein ':' und kein start mit '/' oder '\' 3 - kind=src mit ohne starting
206      * '/' oder '\' 4 - kind=var 5 - kind=lib ein ':' oder start mit '/' oder '\' 6 - rest 7 - kind=output
207      * 
208      * @param classpath the classpath to sort
209      * @return dom-tree representing ordered classpath
210      */
211     private Xpp3Dom orderClasspath( Xpp3Dom classpath )
212     {
213         Xpp3Dom[] children = classpath.getChildren();
214         Arrays.sort( children, new Comparator()
215         {
216             public int compare( Object o1, Object o2 )
217             {
218                 return detectClasspathEntryType( (Xpp3Dom) o1 ) - detectClasspathEntryType( (Xpp3Dom) o2 );
219             }
220         } );
221         Xpp3Dom resultClasspath = new Xpp3Dom( CLASSPATH );
222         for ( int index = 0; index < children.length; index++ )
223         {
224             resultClasspath.addChild( children[index] );
225         }
226         return resultClasspath;
227     }
228 
229     /**
230      * read an xml file (application.xml or .modulemaps).
231      * 
232      * @param xmlFile an xmlfile
233      * @return dom-tree representing the file contents
234      */
235     private Xpp3Dom readXMLFile( File xmlFile )
236     {
237         try
238         {
239             Reader reader = new InputStreamReader( new FileInputStream( xmlFile ), "UTF-8" );
240             Xpp3Dom applicationXmlDom = Xpp3DomBuilder.build( reader );
241             return applicationXmlDom;
242         }
243         catch ( FileNotFoundException e )
244         {
245             return null;
246         }
247         catch ( Exception e )
248         {
249             log.error( Messages.getString( "EclipsePlugin.cantreadfile", xmlFile.getAbsolutePath() ) );
250             // this will trigger creating a new file
251             return null;
252         }
253     }
254 
255     /**
256      * Losche alle pfade die nach was6 zeigen diese sind erkennbar an den parrent runtimes/base_v6/lib.
257      * 
258      * @param classpath classpath to remove was6 libraries
259      */
260     private void removeDupicateWAS6Libs( Xpp3Dom classpath )
261     {
262         Xpp3Dom[] children;
263         children = classpath.getChildren();
264         for ( int index = children.length - 1; index >= 0; index-- )
265         {
266             try
267             {
268                 File path = new File( children[index].getAttribute( PATH ) );
269 
270                 if ( path.exists() && path.getParentFile().getName().equals( LIB ) &&
271                     path.getParentFile().getParentFile().getName().equals( "base_v6" ) &&
272                     path.getParentFile().getParentFile().getParentFile().getName().equals( "runtimes" ) )
273                 {
274                     Xpp3Dom[] currentChildren = classpath.getChildren();
275                     for ( int deleteIndex = currentChildren.length - 1; deleteIndex >= 0; deleteIndex-- )
276                     {
277                         if ( currentChildren[deleteIndex] == children[index] )
278                         {
279                             classpath.removeChild( deleteIndex );
280                             break;
281                         }
282                     }
283                 }
284             }
285             catch ( Exception e )
286             {
287                 log.debug( e );
288             }
289         }
290     }
291 
292 }