root/trunk/src/java/org/jcoderz/commons/taskdefs/MakeReadonlyBeans.java

Revision 1648, 11.2 kB (checked in by amandel, 12 months ago)

Be a bit falt tolerant with the available parser.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 *
4 * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 *    * Redistributions of source code must retain the above copyright
11 *      notice, this list of conditions and the following disclaimer.
12 *    * Redistributions in binary form must reproduce the above
13 *      copyright notice, this list of conditions and the following
14 *      disclaimer in the documentation and/or other materials
15 *      provided with the distribution.
16 *    * Neither the name of the jCoderZ.org Project nor the names of
17 *      its contributors may be used to endorse or promote products
18 *      derived from this software without specific prior written
19 *      permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33package org.jcoderz.commons.taskdefs;
34
35import java.io.File;
36import java.io.FileInputStream;
37import java.io.FileNotFoundException;
38import java.io.InputStream;
39import java.util.ArrayList;
40import java.util.Iterator;
41import java.util.List;
42
43import javax.xml.transform.Transformer;
44import javax.xml.transform.TransformerFactory;
45import javax.xml.transform.sax.SAXSource;
46import javax.xml.transform.stream.StreamResult;
47import javax.xml.transform.stream.StreamSource;
48
49import org.apache.tools.ant.BuildException;
50import org.apache.tools.ant.Project;
51import org.apache.tools.ant.Task;
52import org.xml.sax.InputSource;
53import org.xml.sax.SAXException;
54import org.xml.sax.XMLReader;
55import org.xml.sax.helpers.XMLReaderFactory;
56
57
58
59/**
60 * This task is used to modify a deployment descriptor, making a
61 * copy of the given entity beans with their name changed from
62 * FooEntity to FooReaderEntity. It also modifies the accompanying
63 * weblogic specific deployment descriptors.
64 * @author Albrecht Messner
65 */
66public class MakeReadonlyBeans
67      extends Task
68{
69   private static final String STYLE_GENERIC = "make-readonly-bean-generic.xsl";
70   private static final String STYLE_WEBLOGIC = "make-readonly-bean-wl.xsl";
71   private static final String STYLE_WEBLOGIC_CMP
72         = "make-readonly-bean-wlcmp.xsl";
73   private static final String STYLE_GENERATE_UTIL
74         = "generate-readonly-entity-util.xsl";
75
76   /** The output directory. */
77   private File mDestDir;
78
79   /** The generic deployment descriptor (ejb-jar.xml) to transform. */
80   private File mGenericDeploymentDescriptor = null;
81
82   /**
83    * The weblogic ejb deployment descriptor (weblogic-ejb-jar.xml) to
84    * transform.
85    */
86   private File mWlsDeploymentDescriptor = null;
87
88   /**
89    * The weblogic RDBMS deployment descriptor (weblogic-cmp-rdbms-jar.xml)
90    * to transform.
91    */
92   private File mWlsCmpDeploymentDescriptor = null;
93
94   /** List of all beans that need to be made read-only. */
95   private final List mReadonlyBeans = new ArrayList();
96
97   /** force output of target files even if they already exist. */
98   private boolean mForce = false;
99
100   /** terminate ant build on error. */
101   private boolean mFailOnError = false;
102
103   /** The directory to which generated source files should be written. */
104   private File mSourceDestDir;
105
106   /**
107    * Set the destination directory into which the XSL result
108    * files should be copied to. This parameter is required.
109    * @param dir the name of the destination directory.
110    **/
111   public void setDestdir (File dir)
112   {
113       mDestDir = dir;
114   }
115
116   public void setSourceDestdir (File dir)
117   {
118      mSourceDestDir = dir;
119   }
120
121   /**
122    * Sets the force output of target files flag to the given value.
123    *
124    * @param b Whether we should force the generation of output files.
125    */
126   public void setForce (boolean b)
127   {
128      mForce = b;
129   }
130
131   /**
132    * Set whether we should fail on an error.
133    *
134    * @param b Whether we should fail on an error.
135    */
136   public void setFailonerror (boolean b)
137   {
138      mFailOnError = b;
139   }
140
141   public void setDeploymentDescriptor (File f)
142   {
143      mGenericDeploymentDescriptor = f;
144   }
145
146   public void setWeblogicDeploymentDescriptor (File f)
147   {
148      mWlsDeploymentDescriptor = f;
149   }
150
151   public void setWeblogicCmpDeploymentDescriptor (File f)
152   {
153      mWlsCmpDeploymentDescriptor = f;
154   }
155
156   public ReadOnlyBean createReadOnlyBean ()
157   {
158      final ReadOnlyBean bn = new ReadOnlyBean();
159      mReadonlyBeans.add(bn);
160      return bn;
161   }
162
163   /** {@inheritDoc} */
164   public void execute ()
165         throws BuildException
166   {
167      try
168      {
169         checkFilesAndDirectories();
170
171         if (mForce || checkIfBuildRequired())
172         {
173            final File genericDdTarget
174                  = new File(mDestDir, mGenericDeploymentDescriptor.getName());
175            transform(mGenericDeploymentDescriptor,
176                  genericDdTarget,
177                  STYLE_GENERIC);
178            transform(mWlsDeploymentDescriptor,
179                  new File(mDestDir, mWlsDeploymentDescriptor.getName()),
180                  STYLE_WEBLOGIC);
181            transform(mWlsCmpDeploymentDescriptor,
182                  new File(mDestDir, mWlsCmpDeploymentDescriptor.getName()),
183                  STYLE_WEBLOGIC_CMP);
184            transform(genericDdTarget,
185                  new File(mDestDir, "generate-utils-stdout.txt"),
186                  STYLE_GENERATE_UTIL);
187         }
188         else
189         {
190            log("All files are up-to-date.", Project.MSG_INFO);
191         }
192      }
193      catch (BuildException e)
194      {
195         if (mFailOnError)
196         {
197            throw e;
198         }
199         log(e.getMessage(), Project.MSG_ERR);
200      }
201   }
202
203   private String createListOfReadonlyBeans ()
204   {
205      final StringBuffer sbuf = new StringBuffer();
206      for (final Iterator it = mReadonlyBeans.iterator(); it.hasNext(); )
207      {
208         if (sbuf.length() == 0)
209         {
210            sbuf.append('|');
211         }
212         final ReadOnlyBean bean = (ReadOnlyBean) it.next();
213         sbuf.append(bean.getName());
214         sbuf.append('|');
215      }
216      if (sbuf.length() == 0)
217      {
218         sbuf.append("||");
219      }
220      return sbuf.toString();
221   }
222
223   private boolean checkIfBuildRequired ()
224   {
225      final File genericOutFile
226            = new File(mDestDir, mGenericDeploymentDescriptor.getName());
227      final File weblogicOutFile
228            = new File(mDestDir, mWlsDeploymentDescriptor.getName());
229      final File weblogicCmpOutFile
230            = new File(mDestDir, mWlsCmpDeploymentDescriptor.getName());
231      boolean buildRequired = false;
232      if (! genericOutFile.exists()
233            || genericOutFile.lastModified()
234               < mGenericDeploymentDescriptor.lastModified())
235      {
236         buildRequired = true;
237      }
238      if (! weblogicOutFile.exists()
239            || weblogicOutFile.lastModified()
240               < mWlsDeploymentDescriptor.lastModified())
241      {
242         buildRequired = true;
243      }
244      if (! weblogicCmpOutFile.exists()
245            || weblogicCmpOutFile.lastModified()
246               < mWlsCmpDeploymentDescriptor.lastModified())
247      {
248         buildRequired = true;
249      }
250      return buildRequired;
251   }
252
253   private void checkFilesAndDirectories ()
254   {
255      checkFile("genericDeploymentDescriptor", mGenericDeploymentDescriptor);
256      checkFile("weblogicDeploymentDescriptor", mWlsDeploymentDescriptor);
257      checkFile("weblogicCmpDeploymentDescriptor", mWlsCmpDeploymentDescriptor);
258      checkDirectory("destdir", mDestDir);
259      checkDirectory("sourceDestdir", mSourceDestDir);
260   }
261
262   private void checkFile (String paramName, File file)
263   {
264      if (file == null)
265      {
266         throw new BuildException(
267               "Mandatory attribute '" + paramName + "' is missing.");
268      }
269      if (! file.exists())
270      {
271         throw new BuildException("File '" + file + "' does not exist");
272      }
273   }
274
275   private void checkDirectory (String paramName, File directory)
276   {
277      if (directory == null)
278      {
279         throw new BuildException(
280               "Mandatory attribute '" + paramName + "' missing.");
281      }
282      if (! directory.exists())
283      {
284         throw new BuildException(
285               "Output directory '" + directory + "' does not exist.");
286      }
287      if (! directory.isDirectory())
288      {
289         throw new BuildException("'" + directory + "' is not a directory");
290      }
291   }
292
293   /**
294    * Execute the XSL transformation.
295    * @throws BuildException if an error during transformation occurs.
296    */
297   private void transform (File inFile, File outFile, String xslFile)
298         throws BuildException
299   {
300      try
301      {
302         // Xalan2 transformator is required,
303         // that why we explicit use this factory
304         final TransformerFactory factory
305               = new org.apache.xalan.processor.TransformerFactoryImpl();
306         factory.setURIResolver(new JarArchiveUriResolver(this));
307
308         final InputStream xslStream
309            = LogMessageGenerator.class.getResourceAsStream(xslFile);
310
311         final Transformer transformer
312               = factory.newTransformer(new StreamSource(xslStream));
313
314         transformer.setParameter("outdir", mDestDir.getAbsolutePath());
315         transformer.setParameter("srcdir", mSourceDestDir.getAbsolutePath());
316         transformer.setParameter("bean-names", createListOfReadonlyBeans());
317
318         final StreamResult out = new StreamResult(outFile);
319
320         transformer.transform(getSaxSource(inFile), out);
321      }
322      catch (Exception e)
323      {
324         throw new BuildException("Error during transformation: " + e, e);
325      }
326   }
327
328   private SAXSource getSaxSource (File xmlFile)
329         throws SAXException, FileNotFoundException
330   {
331      final XMLReader xr = getXmlReader();
332      xr.setEntityResolver(new DummyEntityResolver(this));
333      final FileInputStream fileInStream = new FileInputStream(xmlFile);
334      final InputSource inSource = new InputSource(fileInStream);
335      return new SAXSource(xr, inSource);
336   }
337
338   private static XMLReader getXmlReader()
339         throws SAXException
340   {
341      XMLReader result;
342      try
343      {
344        result = XMLReaderFactory.createXMLReader(
345            "org.apache.xerces.parsers.SAXParser");
346      }
347      catch (Exception ex)
348      {
349        // log this?
350        result = XMLReaderFactory.createXMLReader();
351      }
352      return result;
353   }
354   
355   public final class ReadOnlyBean
356   {
357      private String mName;
358
359      /**
360       * @return Returns the beanName.
361       */
362      public String getName ()
363      {
364         return mName;
365      }
366
367      /**
368       * @param beanName The beanName to set.
369       */
370      public void setName (String beanName)
371      {
372         mName = beanName;
373      }
374   }
375}
Note: See TracBrowser for help on using the browser.