KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > deployment > archivist > Archivist


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.deployment.archivist;
25
26 import static com.sun.enterprise.deployment.io.DescriptorConstants.PERSISTENCE_DD_ENTRY;
27
28 import java.io.*;
29 import java.util.jar.*;
30 import java.util.jar.Attributes.Name;
31 import java.util.zip.*;
32 import java.util.*;
33 import java.util.logging.Level JavaDoc;
34 import java.util.logging.Logger JavaDoc;
35
36 import org.xml.sax.SAXParseException JavaDoc;
37 import org.xml.sax.InputSource JavaDoc;
38
39 import javax.enterprise.deploy.shared.ModuleType JavaDoc;
40
41 import com.sun.enterprise.deployment.annotation.AnnotatedElementHandler;
42 import com.sun.enterprise.deployment.annotation.AnnotationProcessor;
43 import com.sun.enterprise.deployment.annotation.AnnotationProcessorException;
44 import com.sun.enterprise.deployment.annotation.ErrorHandler;
45 import com.sun.enterprise.deployment.annotation.ResultType;
46 import com.sun.enterprise.deployment.annotation.factory.AnnotatedElementHandlerFactory;
47 import com.sun.enterprise.deployment.annotation.factory.ScannerFactory;
48 import com.sun.enterprise.deployment.annotation.factory.SJSASFactory;
49 import com.sun.enterprise.deployment.annotation.impl.AnnotationUtils;
50 import com.sun.enterprise.deployment.annotation.impl.DefaultErrorHandler;
51 import com.sun.enterprise.deployment.annotation.ProcessingContext;
52 import com.sun.enterprise.deployment.annotation.ProcessingResult;
53 import com.sun.enterprise.deployment.annotation.Scanner;
54 import com.sun.enterprise.deployment.deploy.shared.AbstractArchive;
55 import com.sun.enterprise.deployment.deploy.shared.AbstractArchiveFactory;
56 import com.sun.enterprise.deployment.deploy.shared.JarArchiveFactory;
57 import com.sun.enterprise.deployment.deploy.shared.Archive;
58 import com.sun.enterprise.deployment.io.*;
59 import com.sun.enterprise.deployment.*;
60 import com.sun.enterprise.deployment.util.DescriptorVisitor;
61 import com.sun.enterprise.deployment.util.DOLUtils;
62 import com.sun.enterprise.deployment.backend.OptionalPkgDependency;
63 import com.sun.enterprise.deployment.backend.IASDeploymentException;
64 import com.sun.enterprise.deployment.util.ModuleDescriptor;
65 import com.sun.enterprise.deployment.util.TracerVisitor;
66 import com.sun.enterprise.util.LocalStringManagerImpl;
67 import com.sun.enterprise.util.shared.ArchivistUtils;
68 import com.sun.enterprise.util.io.FileUtils;
69 import com.sun.logging.LogDomains;
70
71 /**
72  * This abstract class contains all common behaviour for Achivisits. Archivists
73  * classes are responsible for reading and writing correct J2EE Archives
74  *
75  * @author Jerome Dochez
76  * @version
77  */

78 public abstract class Archivist {
79     protected static final Logger JavaDoc logger =
80             LogDomains.getLogger(LogDomains.DPL_LOGGER);
81
82     static {
83         AnnotationUtils.setLogger(logger);
84         AnnotationUtils.setLoggerTarget("*");
85     }
86
87     public static String JavaDoc MANIFEST_VERSION_VALUE = "1.0";
88
89     // the path for the underlying archive file
90
protected String JavaDoc path;
91
92     // should we read or save the runtime info.
93
protected boolean handleRuntimeInfo = true;
94
95     // default should be false in production
96
protected boolean annotationProcessingRequested = false;
97     
98     // attributes of this archive
99
protected Manifest manifest;
100     
101     // the archive abstraction we use to access the physical storage
102
protected AbstractArchiveFactory abstractArchiveFactory= null;
103     
104     /**
105      * plugable archivist factory for creating sub modules archivists
106      */

107     protected PluggableArchivists pa = null;
108     
109     // resources...
110
private static LocalStringManagerImpl localStrings =
111         new LocalStringManagerImpl(Archivist.class);
112     
113     // class loader to use when validating the DOL
114
protected ClassLoader JavaDoc classLoader=null;
115     
116     // boolean for XML validation
117
private boolean isValidatingXML = true;
118
119     // boolean for runtime XML validation
120
private boolean isValidatingRuntimeXML = false;
121     
122     // xml validation error level reporting/recovering
123
private String JavaDoc validationLevel = "parsing";
124
125     // runtime xml validation error level reporting/recovering
126
private String JavaDoc runtimeValidationLevel = "parsing";
127
128     // error handler for annotation processing
129
private ErrorHandler annotationErrorHandler = null;
130
131     private static String JavaDoc WSDL = ".wsdl";
132     private static String JavaDoc XML = ".xml";
133     private static String JavaDoc XSD = ".xsd";
134
135
136     protected static String JavaDoc APPLICATION_EXTENSION = ".ear";
137     protected static String JavaDoc APPCLIENT_EXTENSION = ".jar";
138     protected static String JavaDoc WEB_EXTENSION = ".war";
139     protected static String JavaDoc EJB_EXTENSION = ".jar";
140     protected static String JavaDoc CONNECTOR_EXTENSION = ".rar";
141     //Used to detect the uploaded files which always end in ".tmp"
142
protected static String JavaDoc UPLOAD_EXTENSION = ".tmp";
143
144     private static String JavaDoc PROCESS_ANNOTATION_FOR_OLD_DD =
145         "process.annotation.for.old.dd";
146
147     private static boolean processAnnotationForOldDD =
148         Boolean.getBoolean(PROCESS_ANNOTATION_FOR_OLD_DD);
149
150     /** Creates new Archivist */
151     public Archivist() {
152         // by default we are dealing with jar files, can be changed with
153
// setAbstractArchiveFactory
154
abstractArchiveFactory = new JarArchiveFactory();
155         annotationErrorHandler = new DefaultErrorHandler();
156     }
157     
158     /**
159      * initializes this instance from another archivist, this is used
160      * to transfer contextual information between archivists, for
161      * example whether we should handle runtime information and such
162      */

163     protected void initializeContext(Archivist other) {
164         handleRuntimeInfo = other.isHandlingRuntimeInfo();
165         annotationProcessingRequested = other.isAnnotationProcessingRequested();
166         isValidatingXML = other.isValidatingXML;
167         validationLevel = other.validationLevel;
168         abstractArchiveFactory = other.getAbstractArchiveFactory();
169         classLoader = other.classLoader;
170         annotationErrorHandler = other.annotationErrorHandler;
171     }
172     
173     /**
174      * sets the abstract archive factory associated with this archivist.
175      * @param the new factory for creating abstract archives
176      */

177     public void setAbstractArchiveFactory(AbstractArchiveFactory aa) {
178         abstractArchiveFactory = aa;
179     }
180     
181     /**
182      * @return the currently associated abstract archive factory
183      */

184     public AbstractArchiveFactory getAbstractArchiveFactory() {
185         return abstractArchiveFactory;
186     }
187     
188     /**
189      * Open a new archive file, read the XML descriptor and set the constructed
190      * DOL descriptor instance
191      *
192      * @param path the archive file path
193      * @return the deployment descriptor for this archive
194      */

195     public RootDeploymentDescriptor open(AbstractArchive archive)
196         throws IOException, SAXParseException JavaDoc {
197
198         setManifest(archive.getManifest());
199         
200         RootDeploymentDescriptor descriptor = readDeploymentDescriptors(archive);
201         if (descriptor!=null){
202             postOpen(descriptor, archive);
203         }
204         return descriptor;
205     }
206     
207     /**
208      * Open a new archive file, read the XML descriptor and set the constructed
209      * DOL descriptor instance
210      *
211      * @param path the archive file path
212      * @return the deployment descriptor for this archive
213      */

214     public RootDeploymentDescriptor open(String JavaDoc path)
215         throws IOException, SAXParseException JavaDoc {
216
217         this.path = path;
218     File file = new File(path);
219     if (!file.exists()) {
220         throw new FileNotFoundException(path);
221     }
222         AbstractArchive abstractArchive = abstractArchiveFactory.openArchive(path);
223         RootDeploymentDescriptor descriptor = open(abstractArchive);
224         
225         abstractArchive.close();
226      
227         // attempt validation
228
validate(null);
229
230         return descriptor;
231     }
232     
233     /**
234      * open a new archive file using a file descriptor
235      * @param the archive to open
236      */

237     public RootDeploymentDescriptor open(File file) throws IOException, SAXParseException JavaDoc {
238         return open(file.getAbsolutePath());
239     }
240     
241     /**
242      * perform any action after all standard DDs is read
243      * @param the deployment descriptor for the module
244      * @param the module archive
245      */

246     protected void postStandardDDsRead(RootDeploymentDescriptor descriptor,
247             AbstractArchive archive) throws IOException {
248     }
249     
250     /**
251      * perform any action after annotation processed
252      * @param the deployment descriptor for the module
253      * @param the module archive
254      */

255     protected void postAnnotationProcess(RootDeploymentDescriptor descriptor,
256             AbstractArchive archive) throws IOException {
257     }
258
259     /**
260      * perform any action after all runtime DDs read
261      * @param the deployment descriptor for the module
262      * @param the module archive
263      */

264     protected void postRuntimeDDsRead(RootDeploymentDescriptor descriptor,
265             AbstractArchive archive) throws IOException {
266     }
267
268     /**
269      * perform any post deployment descriptor reading action
270      *
271      * @param the deployment descriptor for the module
272      * @param the module archive
273      */

274     protected void postOpen(RootDeploymentDescriptor descriptor, AbstractArchive archive)
275         throws IOException
276     {
277     }
278
279     /**
280      * Read the standard deployment descriptors (can contained in one or
281      * many file) and return the corresponding initialized descriptor instance.
282      * By default, the standard deployment descriptors are all contained in
283      * the xml file characterized with the path returned by
284      * @see getDeploymentDescriptorPath
285      *
286      * @return the initialized descriptor
287      */

288     public RootDeploymentDescriptor readDeploymentDescriptors(AbstractArchive abstractArchive)
289         throws IOException, SAXParseException JavaDoc {
290             
291         // read the standard deployment descriptors
292
BundleDescriptor descriptor = (BundleDescriptor)readStandardDeploymentDescriptor(abstractArchive);
293
294         ModuleDescriptor newModule = createModuleDescriptor(descriptor);
295         newModule.setArchiveUri(abstractArchive.getArchiveUri());
296         
297         readWebServicesDescriptor(abstractArchive, descriptor);
298
299         // Now that we have parsed the standard DD, let's read all the
300
// PersistenceUnits defined in this archive as well.
301
readPersistenceDeploymentDescriptors(abstractArchive, getDescriptor());
302
303         postStandardDDsRead(descriptor, abstractArchive);
304
305         readAnnotations(abstractArchive, descriptor);
306         postAnnotationProcess(descriptor, abstractArchive);
307
308         // now read the runtime deployment descriptors
309
readRuntimeDeploymentDescriptor(abstractArchive, descriptor);
310         postRuntimeDDsRead(descriptor, abstractArchive);
311     
312     return descriptor;
313     }
314
315     protected void readAnnotations(AbstractArchive abstractArchive, BundleDescriptor descriptor) throws IOException {
316         // if the system property is set to process annotation for pre-JavaEE5
317
// DD, the semantics of isFull flag is: full attribute is set to
318
// true in DD. Otherwise the semantics is full attribute set to
319
// true or it is pre-JavaEE5 DD.
320
boolean isFull = false;
321         if (processAnnotationForOldDD) {
322             isFull = descriptor.isFullAttribute();
323         } else {
324             isFull = descriptor.isFullFlag();
325         }
326
327         // only process annotation when these two requirements satisfied:
328
// 1. It is not a full deployment descriptor
329
// 2. It is called through dynamic deployment
330
if (!isFull && annotationProcessingRequested
331             && classLoader != null) {
332             try {
333                 ProcessingResult result = processAnnotations(descriptor, abstractArchive);
334                 if (result != null &&
335                         ResultType.FAILED.equals(result.getOverallResult())){
336                     DOLUtils.getDefaultLogger().severe(localStrings.getLocalString(
337                             "enterprise.deployment.archivist.annotationprocessingfailed",
338                             "Annotations processing failed for {0}",
339                             new Object JavaDoc[]{abstractArchive.getArchiveUri()}));
340                 }
341             //XXX for backward compatible in case of having cci impl in EJB
342
} catch(NoClassDefFoundError JavaDoc err) {
343                  if (DOLUtils.getDefaultLogger().isLoggable(Level.WARNING)) {
344                      DOLUtils.getDefaultLogger().warning(
345                          "Error in annotation processing: " + err);
346                  }
347             } catch(AnnotationProcessorException ex) {
348                 DOLUtils.getDefaultLogger().severe(ex.getMessage());
349                 DOLUtils.getDefaultLogger().log(Level.FINE, ex.getMessage(), ex);
350                 throw new IllegalStateException JavaDoc(ex);
351             }
352         } else if (DOLUtils.getDefaultLogger().isLoggable(Level.FINE)) {
353             DOLUtils.getDefaultLogger().fine("Annotation is not processed for this archive.");
354         }
355     }
356
357     /**
358      * This method is responsible for reading of any persistence DD defined
359      * in the SCOPE of this descriptor. Note, it only reads persistence DD
360      * defined in the current SCOPE.
361      * @param archive is the archive that will be scanned for persistence DD
362      * @param descriptor which will be populated with information read from
363      * persistence DD.
364      * @throws IOException
365      * @throws SAXParseException
366      */

367     public void readPersistenceDeploymentDescriptors(
368             AbstractArchive archive, Descriptor descriptor)
369             throws IOException, SAXParseException JavaDoc {
370         // This is a no-op implementation as opposed to an abstract method
371
// because it gets called from ConnectorArchivist.
372
}
373
374     /**
375      * Process annotations in a bundle descriptor, the annoation processing
376      * is dependent on the type of descriptor being passed.
377      */

378     public ProcessingResult processAnnotations(BundleDescriptor bundleDesc,
379             AbstractArchive abstractArchive)
380             throws AnnotationProcessorException, IOException {
381
382         AnnotatedElementHandler aeHandler =
383                 AnnotatedElementHandlerFactory.createAnnotatedElementHandler(
384                 bundleDesc);
385
386         if (aeHandler == null) {
387             return null;
388         }
389         
390         Scanner scanner = ScannerFactory.createScanner(
391                 bundleDesc, this, abstractArchive, classLoader);
392         if (!scanner.getElements().isEmpty()) {
393             if (bundleDesc.isDDWithNoAnnotationAllowed()) {
394                 // if we come into this block, it means an old version
395
// of deployment descriptor has annotation which is not correct
396
// throw exception in this case
397
String JavaDoc ddName =
398                     getStandardDDFile().getDeploymentDescriptorPath();
399                 String JavaDoc explodedArchiveName =
400                     new File(abstractArchive.getArchiveUri()).getName();
401                 String JavaDoc archiveName = FileUtils.revertFriendlyFilenameExtension(
402                     explodedArchiveName);
403                 throw new AnnotationProcessorException(
404                     localStrings.getLocalString(
405                     "enterprise.deployment.oldDDwithAnnotation",
406                     "{0} in archive {1} is of version {2}, which cannot support annotations in an application. Please upgrade the deployment descriptor to be a version supported by Java EE 5.0 (or later).",
407                     new Object JavaDoc[] {ddName, archiveName, bundleDesc.getSpecVersion()}));
408             }
409             AnnotationProcessor ap = SJSASFactory.getAnnotationProcessor();
410             ProcessingContext ctx = ap.createContext();
411             if (annotationErrorHandler != null) {
412                 ctx.setErrorHandler(annotationErrorHandler);
413             }
414             ctx.setProcessingInput(scanner);
415             ctx.pushHandler(aeHandler);
416             
417             // Make sure there is a classloader available on the descriptor
418
// during annotation processing.
419
ClassLoader JavaDoc originalBundleClassLoader = null;
420             try {
421                 originalBundleClassLoader = bundleDesc.getClassLoader();
422             } catch(Exception JavaDoc e) {
423                 // getClassLoader can throw exception if not available
424
}
425             
426             // Only set classloader if it's not already set.
427
if( originalBundleClassLoader == null ) {
428                 bundleDesc.setClassLoader(classLoader);
429             }
430             
431             try {
432                 return ap.process(ctx);
433             } finally {
434                 if( originalBundleClassLoader == null ) {
435                     bundleDesc.setClassLoader(null);
436                 }
437             }
438         } else {
439             bundleDesc.setFullFlag(true);
440         }
441         return null;
442     }
443
444     /**
445      * Read the standard deployment descriptors (can contained in one or
446      * many file) and return the corresponding initialized descriptor instance.
447      * By default, the standard deployment descriptors are all contained in
448      * the xml file characterized with the path returned by
449      * @see getDeploymentDescriptorPath
450      *
451      * @return the initialized descriptor
452      */

453     public Descriptor readStandardDeploymentDescriptor(AbstractArchive abstractArchive)
454         throws IOException, SAXParseException JavaDoc {
455
456         InputStream is = null;
457         
458         try {
459             is = abstractArchive.getEntry(getStandardDDFile().getDeploymentDescriptorPath());
460             if (is!=null) {
461                 DeploymentDescriptorFile ddFile = getStandardDDFile();
462                 ddFile.setXMLValidation(getXMLValidation());
463                 ddFile.setXMLValidationLevel(validationLevel);
464                 if (abstractArchive.getArchiveUri()!=null) {
465                     ddFile.setErrorReportingString(abstractArchive.getArchiveUri());
466                 }
467                 Descriptor result = ddFile.read(is);
468                 return result;
469             } else {
470                 /*
471                  *Always return at least the default, because the info is needed
472                  *when an app is loaded during a server restart and there might not
473                  *be a physical descriptor file.
474                  */

475                 return getDefaultBundleDescriptor();
476             }
477         } finally {
478             if (is != null) {
479                 is.close();
480             }
481         }
482     }
483
484     /**
485      * Read the runtime deployment descriptors (can contained in one or
486      * many file) set the corresponding information in the passed descriptor.
487      * By default, the runtime deployment descriptors are all contained in
488      * the xml file characterized with the path returned by
489      * @see getRuntimeDeploymentDescriptorPath
490      *
491      * @param the initialized deployment descriptor
492      */

493     public void readRuntimeDeploymentDescriptor(AbstractArchive abstractArchive, Descriptor descriptor)
494         throws IOException, SAXParseException JavaDoc {
495         
496         // if we are not supposed to handle runtime info, just pass
497
String JavaDoc ddFileEntryName = getRuntimeDeploymentDescriptorPath();
498         if (!isHandlingRuntimeInfo() || ddFileEntryName==null) {
499             return;
500         }
501         
502         InputStream is = null;
503         try {
504             // apply the runtime settings if any
505
is = abstractArchive.getEntry(ddFileEntryName);
506             DeploymentDescriptorFile confDD = getConfigurationDDFile();
507             if (abstractArchive.getArchiveUri()!=null) {
508                 confDD.setErrorReportingString(abstractArchive.getArchiveUri());
509             }
510         
511             if (is!=null && confDD!=null) {
512                 confDD.setXMLValidation(getRuntimeXMLValidation());
513                 confDD.setXMLValidationLevel(runtimeValidationLevel);
514                 confDD.read(descriptor, is);
515             }
516         } finally {
517             if (is != null) {
518                 try {
519                     is.close();
520                 } catch (IOException ioe) {
521                 }
522             }
523         }
524     }
525
526     /**
527      * Read the runtime deployment descriptors (can contained in one or
528      * many file) from a deployment plan archive, set the corresponding
529      * information in the passed descriptor.
530      */

531     public void readRuntimeDDFromDeploymentPlan(
532             AbstractArchive planArchive, Descriptor descriptor)
533         throws IOException, SAXParseException JavaDoc {
534         
535         // if we are not supposed to handle runtime info, just pass
536
String JavaDoc runtimeDDPath = getRuntimeDeploymentDescriptorPath();
537         if (runtimeDDPath==null || planArchive==null) {
538             return;
539         }
540
541         // list of entries in the deployment plan
542
Vector dpEntries = new Vector();
543         for (Enumeration e = planArchive.entries(); e.hasMoreElements();) {
544             dpEntries.add(e.nextElement());
545         }
546
547         String JavaDoc entry = runtimeDDPath.substring(runtimeDDPath.lastIndexOf('/')+1);
548         if (dpEntries.contains(entry)) {
549             readRuntimeDDFromDeploymentPlan(entry, planArchive, descriptor);
550         }
551     }
552
553     /**
554      * Read the runtime deployment descriptors (can contained in one or
555      * many file) from a deployment plan archive, set the corresponding
556      * information in the passed descriptor.
557      */

558     protected void readRuntimeDDFromDeploymentPlan(
559         String JavaDoc entry, AbstractArchive planArchive, Descriptor descriptor)
560         throws IOException, SAXParseException JavaDoc {
561
562         InputStream is = null;
563         try {
564             is = planArchive.getEntry(entry);
565             DeploymentDescriptorFile confDD = getConfigurationDDFile();
566             if (is!=null && confDD!=null) {
567                 if (planArchive.getArchiveUri()!=null) {
568                     confDD.setErrorReportingString(planArchive.getArchiveUri());
569                 }
570                 confDD.setXMLValidation(getXMLValidation());
571                 confDD.read(descriptor, is);
572             }
573         } finally {
574             if (is != null) {
575             try {
576                 is.close();
577             } catch (IOException ioe) { }
578             }
579         }
580     }
581
582     /**
583      * Read the (optional) webservices.xml descriptor in this module.
584      * Only applicable for web and ejb modules.
585      */

586     protected void readWebServicesDescriptor(AbstractArchive abstractArchive,
587                                           Descriptor descriptor)
588         throws IOException, SAXParseException JavaDoc {
589
590         DeploymentDescriptorFile confDD = getWebServicesDDFile(descriptor);
591         if (abstractArchive.getArchiveUri()!=null) {
592             confDD.setErrorReportingString(abstractArchive.getArchiveUri());
593         }
594         InputStream is = null;
595         try {
596             is = abstractArchive.getEntry(confDD.getDeploymentDescriptorPath());
597             if (is != null) {
598                 confDD.setXMLValidation(getXMLValidation());
599                 confDD.setXMLValidationLevel(validationLevel);
600                 confDD.read(descriptor, is);
601             }
602         } finally {
603             if (is != null) {
604                 is.close();
605             }
606         }
607
608     }
609
610     /*
611      * write the J2EE module represented by this instance to a new
612      * J2EE archive file
613      *
614      */

615     public void write() throws IOException {
616         write(path);
617     }
618     
619     /**
620      * saves the archive
621      *
622      * @param outPath the file to use
623      */

624     public void write(String JavaDoc outPath) throws IOException {
625         AbstractArchive in = abstractArchiveFactory.openArchive(path);
626         write(in, outPath);
627         in.close();
628     }
629     
630     /**
631      * save the archive
632      *
633      * @param input abstract archive to copy old elements from
634      * @param outPath the file to use
635      */

636     public void write(AbstractArchive in, String JavaDoc outPath) throws IOException {
637         
638         AbstractArchive oldArchive=null;
639         try {
640             oldArchive = abstractArchiveFactory.openArchive(outPath);
641         } catch (IOException ioe) {
642             // there could be many reasons why we cannot open this archive,
643
// we should continue
644
}
645         AbstractArchive out = null;
646         File fOut = new File(outPath);
647         BufferedOutputStream bos=null;
648         try {
649             String JavaDoc tmpName = null;
650             if (oldArchive!=null && oldArchive.exists() &&
651                 !oldArchive.supportsElementsOverwriting()) {
652                 // this is a rewrite, get a temp file name...
653
// I am creating a tmp file just to get a name
654
File outputFile = getTempFile(outPath);
655                 tmpName = outputFile.getAbsolutePath();
656                 outputFile.delete();
657                 out = abstractArchiveFactory.createArchive(tmpName);
658                 oldArchive.close();
659             } else {
660                 out = abstractArchiveFactory.createArchive(outPath);
661             }
662         
663             // write archivist content
664
writeContents(in, out);
665             out.close();
666             in.close();
667             
668             // if we were using a temp file, time to rewrite the original
669
if (tmpName!=null) {
670                 AbstractArchive finalArchive = abstractArchiveFactory.openArchive(outPath);
671                 finalArchive.delete();
672                 AbstractArchive tmpArchive = abstractArchiveFactory.openArchive(tmpName);
673                 tmpArchive.renameTo(outPath);
674             }
675         } catch (IOException ioe) {
676             // cleanup
677
if (out!=null) {
678         try {
679                     out.close();
680                     //out.delete(); <-- OutputJarArchive.delete isn't supported.
681
} catch (IOException outIoe) {
682             // ignore exceptions here, otherwise this will end up masking the real
683
// IOException in 'ioe'.
684
}
685             }
686             // propagate exception
687
throw ioe;
688         }
689     }
690     
691     public void write(AbstractArchive in, AbstractArchive out) throws IOException {
692         writeContents(in,out);
693     }
694     
695     /**
696      * writes the content of an archive to a JarFile
697      *
698      * @param the jar output stream to write to
699      */

700     protected void writeContents(AbstractArchive out) throws IOException {
701         AbstractArchive in = abstractArchiveFactory.openArchive(path);
702         writeContents(in, out);
703         in.close();
704     }
705
706     
707     /**
708      * writes the content of an archive to a JarFile
709      *
710      * @param the jar output stream to write to
711      */

712     protected void writeContents(AbstractArchive in, AbstractArchive out) throws IOException {
713
714         writeContents(in, out, null);
715     }
716     
717         
718     /**
719      * writes the content of an archive to a JarFile
720      *
721      * @param the input archive
722      * @param the archive output stream to write to
723      * @param the files to not write from the original archive
724      */

725     protected void writeContents(AbstractArchive in, AbstractArchive out, Vector entriesToSkip)
726         throws IOException {
727         
728         // Copy original jarFile elements
729
if (in!=null && in.exists()) {
730             if (entriesToSkip==null) {
731                 entriesToSkip = getListOfFilesToSkip();
732             } else {
733                 entriesToSkip.addAll(getListOfFilesToSkip());
734             }
735             copyJarElements(in, out, entriesToSkip);
736         }
737         
738         // now the deployment descriptors
739
writeDeploymentDescriptors(out);
740         
741         // manifest file
742
if (manifest!=null) {
743             OutputStream os = out.putNextEntry(JarFile.MANIFEST_NAME);
744             manifest.write(new DataOutputStream(os));
745             out.closeEntry();
746         }
747     }
748     
749     /**
750      * writes the deployment descriptors (standard and runtime)
751      * to a JarFile using the right deployment descriptor path
752      *
753      * @out the abstract archive file to write to
754      */

755     public void writeDeploymentDescriptors(AbstractArchive out) throws IOException {
756         
757         // Standard DDs
758
writeStandardDeploymentDescriptors(out);
759     
760         // the rest...
761
writeExtraDeploymentDescriptors(out);
762     }
763     
764     /**
765      * writes the standard deployment descriptors to an abstract archive
766      *
767      * @param the abstract archive to write to
768      */

769     public void writeStandardDeploymentDescriptors(AbstractArchive out) throws IOException {
770         
771         OutputStream os = out.putNextEntry(getDeploymentDescriptorPath());
772         writeStandardDeploymentDescriptors(os);
773         out.closeEntry();
774         
775         Descriptor desc = getDescriptor();
776         
777         // only bundle descriptor can have web services
778
if (desc instanceof BundleDescriptor) {
779             writeWebServicesDescriptors((BundleDescriptor) desc, out);
780         }
781     }
782     
783     /**
784      * writes the runtime deployment descriptors to an abstract archive
785      *
786      * @param the abstract archive
787      */

788     public void writeRuntimeDeploymentDescriptors(AbstractArchive out) throws IOException {
789         
790         Descriptor desc = getDescriptor();
791
792         // Runtime DDs
793
if (isHandlingRuntimeInfo()) {
794             DeploymentDescriptorFile confDD = getConfigurationDDFile();
795             if (confDD!=null) {
796                 OutputStream os = out.putNextEntry(getRuntimeDeploymentDescriptorPath());
797                 confDD.write(desc, os);
798                 out.closeEntry();
799             }
800         }
801         
802     }
803     
804     /**
805      * write all extra deployment descriptors (like cmp related and runtime dds)
806      *
807      * @out the abstract archive file to write to
808      */

809     protected void writeExtraDeploymentDescriptors(AbstractArchive out) throws IOException {
810     writeRuntimeDeploymentDescriptors(out);
811     }
812     
813     /**
814      * writes the standard deployment descriptor to an output stream
815      *
816      * @param output stream to write out the descriptors
817      */

818     public void writeStandardDeploymentDescriptors(OutputStream os) throws IOException {
819         getStandardDDFile().write(getDescriptor(), os);
820     }
821     
822     /**
823      * writes de configuration deployment descriptor to a new XML file
824      *
825      * @param output stream to write the configuration deployment descriptors
826      */

827     public void writeRuntimeDeploymentDescriptors(OutputStream os) throws IOException {
828         DeploymentDescriptorFile confDD = getConfigurationDDFile();
829         if (confDD!=null) {
830             confDD.write(getDescriptor(), os);
831         }
832     }
833     
834     /**
835      * @return whether this archivist should write a web services
836      * deployment descriptor
837      */

838     protected void writeWebServicesDescriptors(BundleDescriptor desc, AbstractArchive out)
839         throws IOException {
840         if (desc.hasWebServices()) {
841             DeploymentDescriptorFile webServicesDD = getWebServicesDDFile(desc);
842             OutputStream os = out.putNextEntry(webServicesDD.getDeploymentDescriptorPath());
843             webServicesDD.write(desc, os);
844             out.closeEntry();
845         }
846     }
847     
848     /**
849      * @return the location of the DeploymentDescriptor file for a
850      * particular type of J2EE Archive
851      */

852     public String JavaDoc getDeploymentDescriptorPath() {
853         return getStandardDDFile().getDeploymentDescriptorPath();
854     }
855     
856     /**
857      * @return the location of the web services related deployment
858      * descriptor file inside this archive or null if this archive
859      * does not support webservices implementation.
860      */

861     public String JavaDoc getWebServicesDeploymentDescriptorPath() {
862         return null;
863     }
864
865     /**
866      * @return the location of the runtime deployment descriptor file
867      * for a particular type of J2EE Archive
868      */

869     public String JavaDoc getRuntimeDeploymentDescriptorPath() {
870         DeploymentDescriptorFile ddFile = getConfigurationDDFile();
871         if (ddFile!=null) {
872             return ddFile.getDeploymentDescriptorPath();
873         } else {
874             return null;
875         }
876     }
877     
878     /**
879      * @return true if the passed AbstractArchive contains runtime
880      * deployment descriptors information
881      */

882     public boolean containsRuntimeDeploymentDescriptors(AbstractArchive in) {
883         
884         String JavaDoc ddFileName = getRuntimeDeploymentDescriptorPath();
885         if (ddFileName==null) {
886             return false;
887         }
888         for (Enumeration e = in.entries();e.hasMoreElements();) {
889             String JavaDoc entryName = (String JavaDoc) e.nextElement();
890             if (entryName.equals(ddFileName)) {
891                 return true;
892             }
893         }
894         // we iterated all archive elements, could not find our
895
// runtime DD file, it's a pure j2ee archive
896
return false;
897     }
898
899     /**
900      * Archivists can be associated with a module descriptor once the
901      * XML deployment descriptors have been read and the DOL tree
902      * is initialized.
903      */

904     public void setModuleDescriptor(ModuleDescriptor module) {
905         setDescriptor(module.getDescriptor());
906         setManifest(module.getManifest());
907     }
908     
909     /**
910      * Perform Optional packages dependencies checking on an archive
911      */

912     public boolean performOptionalPkgDependenciesCheck(AbstractArchive archive) throws IOException {
913         
914         boolean dependenciesSatisfied = true;
915         Manifest m = archive.getManifest();
916         if (m!=null) {
917             dependenciesSatisfied=OptionalPkgDependency.optionalPkgDependencyLogic(m, archive.getArchiveUri());
918         }
919         // now check my libraries.
920
Vector<String JavaDoc> libs = getLibraries(archive);
921         if (libs!=null) {
922             for (String JavaDoc libUri : libs) {
923                 JarInputStream jis=null;
924                 try {
925                     jis = new JarInputStream(archive.getEntry(libUri));
926                     m = jis.getManifest();
927                     if (m!=null) {
928                         if (!OptionalPkgDependency.optionalPkgDependencyLogic(m, libUri)) {
929                             dependenciesSatisfied=false;
930                         }
931                     }
932                 } finally {
933                     if (jis!=null)
934                         jis.close();
935                 }
936             }
937         }
938         return dependenciesSatisfied;
939     }
940     
941     /**
942      * Archivist read XML deployment descriptors and keep the
943      * parsed result in the DOL descriptor instances. Sets the descriptor
944      * for a particular Archivist type
945      */

946     public abstract void setDescriptor(Descriptor descriptor);
947     
948     /**
949      * @return the Descriptor for this archvist
950      */

951     public abstract Descriptor getDescriptor();
952
953     /**
954      * @return the module type handled by this archivist
955      * as defined in the application DTD
956      *
957      */

958     public abstract ModuleType JavaDoc getModuleType();
959     
960     /**
961      * @return the DeploymentDescriptorFile responsible for handling
962      * standard deployment descriptor
963      */

964     public abstract DeploymentDescriptorFile getStandardDDFile();
965     
966     /**
967      * @return if exists the DeploymentDescriptorFile responsible for
968      * handling the configuration deployment descriptors
969      */

970     public abstract DeploymentDescriptorFile getConfigurationDDFile();
971
972     /**
973      * @return a default BundleDescriptor for this archivist
974      */

975     public abstract Descriptor getDefaultBundleDescriptor();
976
977     /**
978      * @param arch archive for this module. can be null. only used for reading
979      * @return the DeploymentDescriptorFile responsible for
980      * handling the web services deployment descriptors
981      */

982     public DeploymentDescriptorFile getWebServicesDDFile(Descriptor desc) {
983         return new WebServicesDeploymentDescriptorFile(desc);
984     }
985
986     /**
987      *@return The archive extension handled by a specific archivist
988      */

989     protected abstract String JavaDoc getArchiveExtension();
990
991     /**
992      * @return true if the archivist is handling the provided archive
993      */

994     protected abstract boolean postHandles(AbstractArchive abstractArchive) throws IOException;
995
996     public boolean hasStandardDeploymentDescriptor(AbstractArchive archive)
997         throws IOException {
998         InputStream stIs = archive.getEntry(getDeploymentDescriptorPath());
999         if (stIs != null) {
1000             stIs.close();
1001             return true;
1002        }
1003        return false;
1004    }
1005
1006    public boolean hasRuntimeDeploymentDescriptor(AbstractArchive archive)
1007        throws IOException {
1008
1009        //check null: since .par archive does not have runtime dds
1010
if (getConfigurationDDFile() != null) {
1011            InputStream runIs = archive.getEntry(
1012                getConfigurationDDFile().getDeploymentDescriptorPath());
1013            if (runIs != null) {
1014                runIs.close();
1015                return true;
1016            }
1017        }
1018        return false;
1019    }
1020    
1021    /**
1022     * creates a new module descriptor for this archivist
1023     * @return the new module descriptor
1024     */

1025    public ModuleDescriptor createModuleDescriptor(BundleDescriptor descriptor) {
1026        ModuleDescriptor newModule = new ModuleDescriptor();
1027        newModule.setModuleType(getModuleType());
1028        newModule.setDescriptor(descriptor);
1029        setDescriptor(descriptor);
1030        return newModule;
1031    }
1032        
1033    
1034    /**
1035     * print the current descriptor associated with this archivist
1036     */

1037    public void printDescriptor() {
1038        getDescriptor().visit((DescriptorVisitor) new TracerVisitor());
1039    }
1040    
1041    /**
1042     * sets if this archivist saves the runtime info
1043     *
1044     * @param true to save the runtime info
1045     */

1046    public void setHandleRuntimeInfo(boolean handleRuntimeInfo) {
1047        this.handleRuntimeInfo = handleRuntimeInfo;
1048    }
1049    
1050    /**
1051     * @return true if this archivist will save the runtime info
1052     */

1053    public boolean isHandlingRuntimeInfo() {
1054        return handleRuntimeInfo;
1055    }
1056    
1057    /**
1058     * sets if this archivist process annotation
1059     *
1060     * @param true to process annotation
1061     */

1062    public void setAnnotationProcessingRequested(
1063                boolean annotationProcessingRequested) {
1064        this.annotationProcessingRequested = annotationProcessingRequested;
1065    }
1066    
1067    /**
1068     * @return true if this archivist will process annotation
1069     */

1070    public boolean isAnnotationProcessingRequested() {
1071        return annotationProcessingRequested;
1072    }
1073    
1074    /**
1075     * sets annotation ErrorHandler for this archivist
1076     *
1077     * @param annotationErrorHandler
1078     */

1079    public void setAnnotationErrorHandler(ErrorHandler annotationErrorHandler) {
1080        this.annotationErrorHandler = annotationErrorHandler;
1081    }
1082    
1083    /**
1084     * @return annotation ErrorHandler of this archivist
1085     */

1086    public ErrorHandler getAnnotationErrorHandler() {
1087        return annotationErrorHandler;
1088    }
1089    
1090    /**
1091     * sets the manifest file for this archive
1092     *
1093     * @param manifest to use at saving time
1094     */

1095    public void setManifest(Manifest m) {
1096        manifest = m;
1097    }
1098    
1099    /**
1100     * @return the manifest file for this archive
1101     */

1102    public Manifest getManifest() {
1103        return manifest;
1104    }
1105    
1106    /**
1107     * Sets the class-path for this archive
1108     *
1109     * @param the new class-path
1110     */

1111    public void setClassPath(String JavaDoc newClassPath) {
1112        
1113        if (manifest==null) {
1114            manifest = new Manifest();
1115        }
1116        
1117        Attributes atts = manifest.getMainAttributes();
1118        atts.putValue(Attributes.Name.CLASS_PATH.toString(), newClassPath);
1119    }
1120    
1121    /**
1122     * @return the class-path as set in the manifest associated
1123     * with the archive
1124     */

1125    public String JavaDoc getClassPath() {
1126        
1127        if (manifest==null) {
1128            return null;
1129        }
1130        
1131        Attributes atts = manifest.getMainAttributes();
1132        return atts.getValue(Attributes.Name.CLASS_PATH);
1133    }
1134    
1135    /**
1136     * @return a list of libraries included in the archivist
1137     */

1138    public Vector getLibraries(AbstractArchive archive) {
1139        
1140        Enumeration<String JavaDoc> entries = archive.entries();
1141        if (entries==null)
1142            return null;
1143        
1144        Vector libs = new Vector();
1145        while (entries.hasMoreElements()) {
1146            
1147            String JavaDoc entryName = entries.nextElement();
1148            if (entryName.indexOf('/')!=-1) {
1149                continue; // not on the top level
1150
}
1151            if (entryName.endsWith(".jar")) {
1152                libs.add(entryName);
1153            }
1154        }
1155        return libs;
1156    }
1157
1158    /**
1159    * @returns an entry name unique amongst names in this archive based on the triel name.
1160    */

1161    protected String JavaDoc getUniqueEntryFilenameFor(AbstractArchive archive, String JavaDoc trialName) throws IOException {
1162        Vector entriesNames = new Vector();
1163        Enumeration e = archive.entries();
1164        while (e!=null && e.hasMoreElements()) {
1165            entriesNames.add(e.nextElement());
1166        }
1167    return Descriptor.createUniqueFilenameAmongst(trialName, entriesNames);
1168    }
1169    
1170    /**
1171     * Add this archive to an application archivist
1172     *
1173     * @param application archive to add itself to
1174     * @param library jars for this archive
1175     * @param external deployment descriptor path
1176     */

1177    protected ModuleDescriptor addToArchive(ApplicationArchivist appArch, String JavaDoc externalDD)
1178        throws IOException, SAXParseException JavaDoc {
1179                 
1180
1181        AbstractArchive archiveToBeAdded = abstractArchiveFactory.openArchive(path);
1182        File archiveFile = new File(path);
1183        AbstractArchive appArchive = abstractArchiveFactory.openArchive(appArch.getArchiveUri());
1184    String JavaDoc archiveName = getUniqueEntryFilenameFor(appArchive, archiveFile.getName());
1185        appArchive.close();
1186        Descriptor descriptor = null;
1187    if (externalDD != null && !"".equals(externalDD)) {
1188            File externalDescriptorFile = new File(externalDD);
1189            if (externalDescriptorFile.exists()) {
1190                FileInputStream fis = new FileInputStream(externalDescriptorFile);
1191                try {
1192                    DeploymentDescriptorFile ddf = getStandardDDFile();
1193                    descriptor = ddf.read(fis);
1194                } catch(SAXParseException JavaDoc pe) {
1195                    archiveToBeAdded.close();
1196                    pe.printStackTrace();
1197                    // propagate
1198
throw pe;
1199                }
1200            }
1201        }
1202        if (descriptor==null) {
1203            // We get the deployment descriptors, including maybe the
1204
// runtime deployment descriptors
1205
descriptor = open(archiveToBeAdded);
1206        }
1207        archiveToBeAdded.close();
1208        
1209        // Create a new module descriptor for this new module
1210
if (descriptor instanceof BundleDescriptor) {
1211            ModuleDescriptor newModule = new ModuleDescriptor();
1212            newModule.setArchiveUri(archiveName);
1213            newModule.setModuleType(getModuleType());
1214            newModule.setDescriptor((BundleDescriptor) descriptor);
1215            newModule.setManifest(getManifest());
1216            if (externalDD != null && !"".equals(externalDD)) {
1217                newModule.setAlternateDescriptor(externalDD);
1218            }
1219            return newModule;
1220        } else {
1221            return null;
1222        }
1223    }
1224        
1225    /**
1226     * prepare an archivist for inclusion in a application archive.
1227     *
1228     * @param archive file where this archivist will be saved
1229     */

1230    protected void prepareForInclusion(AbstractArchive out) throws IOException {
1231    }
1232      
1233    public void saveRuntimeInfo(File output) throws IOException {
1234        // if output file is null, we overwrite the current archive...
1235
File outputFile = output;
1236        if (outputFile==null) {
1237            outputFile = getTempFile(path);
1238        }
1239        
1240        // copy all entries from source to target except the
1241
// runtime descriptor file
1242
AbstractArchive out = abstractArchiveFactory.createArchive(outputFile.getAbsolutePath());
1243        AbstractArchive in = abstractArchiveFactory.openArchive(path);
1244        Vector skipFiles = new Vector();
1245        skipFiles.add(getRuntimeDeploymentDescriptorPath());
1246        copyInto(in, out, skipFiles);
1247        in.close();
1248        
1249        // now save the runtime deployment descriptor...
1250
OutputStream os = out.putNextEntry(getRuntimeDeploymentDescriptorPath());
1251        writeRuntimeDeploymentDescriptors(os);
1252        out.closeEntry();
1253        out.close();
1254        
1255        // if we overwrote the old archive, need to rename the tmp now
1256
if (output==null) {
1257            AbstractArchive finalArchive = abstractArchiveFactory.openArchive(path);
1258            finalArchive.delete();
1259            AbstractArchive tmpArchive = abstractArchiveFactory.openArchive(outputFile.getAbsolutePath());
1260            tmpArchive.renameTo(path);
1261        }
1262        
1263    }
1264    
1265    /**
1266     * apply runtimne info to this archive descriptors and saves it
1267     */

1268    public void applyRuntimeInfo(File runtimeDD, File output) throws IOException, SAXParseException JavaDoc {
1269
1270        // update the runtime info
1271
getConfigurationDDFile().read(getDescriptor(), new FileInputStream(runtimeDD));
1272
1273        // save the runtime info...
1274
saveRuntimeInfo(output);
1275    }
1276    
1277    /**
1278     * utility method to get a tmp file in the current user directory of the provided
1279     * directory
1280     *
1281     * @param File file or directory to use as temp location (use parent directory
1282     * if a file is provided)
1283     */

1284    protected static File getTempFile(String JavaDoc fileOrDirPath) throws IOException {
1285        if (fileOrDirPath!=null) {
1286            return getTempFile(new File(fileOrDirPath));
1287        } else {
1288            return getTempFile((File) null);
1289        }
1290    }
1291    
1292    /**
1293     * @return the list of files that should not be copied from the old archive
1294     * when a save is performed.
1295     */

1296    public Vector getListOfFilesToSkip() {
1297        
1298        Vector filesToSkip = new Vector();
1299        filesToSkip.add(getDeploymentDescriptorPath());
1300        if (manifest!=null) {
1301            filesToSkip.add(JarFile.MANIFEST_NAME);
1302        }
1303        if (getRuntimeDeploymentDescriptorPath()!=null) {
1304            filesToSkip.add(getRuntimeDeploymentDescriptorPath());
1305        }
1306
1307        // Can't depend on having a descriptor, so skip all possible
1308
// web service deployment descriptor paths.
1309
filesToSkip.addAll(WebServicesDeploymentDescriptorFile.
1310                        getAllDescriptorPaths());
1311
1312        return filesToSkip;
1313    }
1314    
1315    /**
1316     * utility method to get a tmp file in the current user directory of the provided
1317     * directory
1318     *
1319     * @param File file or directory to use as temp location (use parent directory
1320     * if a file is provided)
1321     */

1322    protected static File getTempFile(File fileOrDir) throws IOException {
1323        
1324        File dir = null;
1325        if (fileOrDir==null) {
1326            dir=new File(System.getProperty("user.dir"));
1327        } else {
1328            if (!fileOrDir.isDirectory()) {
1329                dir = fileOrDir.getParentFile();
1330                if (dir==null) {
1331                    dir=new File(System.getProperty("user.dir"));
1332                }
1333            } else {
1334                dir = fileOrDir;
1335            }
1336        }
1337        return File.createTempFile("tmp", ".jar", dir);
1338    }
1339    
1340    /**
1341     * add a file to an output abstract archive
1342     *
1343     * @param archive abstraction to use when adding the file
1344     * @param path to the file to add
1345     * @param entryName the entry name in the archive
1346     */

1347    protected static void addFileToArchive(AbstractArchive archive, String JavaDoc filePath, String JavaDoc entryName)
1348        throws IOException {
1349            
1350        FileInputStream is = new FileInputStream(new File(filePath));
1351        OutputStream os = archive.putNextEntry(entryName);
1352        ArchivistUtils.copyWithoutClose(is, os);
1353        is.close();
1354        archive.closeEntry();
1355    }
1356    
1357    /**
1358     * copy all contents of a jar file to a new jar file except
1359     * for all the deployment descriptors files
1360     *
1361     * @param input jar file
1362     * @param output jar file
1363     * @param vector of entry name to not copy from to source jar file
1364     */

1365    protected void copyJarElements(AbstractArchive in, AbstractArchive out, Vector ignoreList)
1366        throws IOException {
1367                    
1368        Enumeration entries = in.entries();
1369        // we need to add the list of existing entries in the output
1370
// archive to the list of files to ignore to avoid any collision
1371
for (Enumeration outEntriesItr = out.entries();outEntriesItr.hasMoreElements();) {
1372            if (ignoreList==null) {
1373                ignoreList = new Vector();
1374            }
1375            ignoreList.add(outEntriesItr.nextElement());
1376        }
1377        if (entries!=null) {
1378            for (;entries.hasMoreElements();) {
1379                String JavaDoc anEntry = (String JavaDoc) entries.nextElement();
1380                if (ignoreList==null || !ignoreList.contains(anEntry)) {
1381                    InputStream is = in.getEntry(anEntry);
1382                    OutputStream os = out.putNextEntry(anEntry);
1383                    ArchivistUtils.copyWithoutClose(is, os);
1384                    is.close();
1385                    out.closeEntry();
1386                }
1387            }
1388        }
1389    }
1390    
1391    /**
1392     * rename a tmp file
1393     *
1394     * @param old name
1395     * @param new name
1396     */

1397    protected boolean renameTmp(String JavaDoc from, String JavaDoc to) throws IOException {
1398        
1399        AbstractArchive finalArchive = abstractArchiveFactory.openArchive(to);
1400        finalArchive.delete();
1401        AbstractArchive tmpArchive = abstractArchiveFactory.openArchive(from);
1402        boolean success = tmpArchive.renameTo(to);
1403        if (!success) {
1404            throw new IOException("Error renaming JAR");
1405        }
1406        return success;
1407    }
1408    
1409    /**
1410     * Sets the path for this archivist's archive file
1411     */

1412    public void setArchiveUri(String JavaDoc path) {
1413        this.path = path;
1414    }
1415    
1416    /**
1417     * @return the path for this archivist's archive file
1418     */

1419    public String JavaDoc getArchiveUri() {
1420        return path;
1421    }
1422    
1423    /**
1424     * Sets the classloader for this archivist
1425     * @param class loader
1426     */

1427    public void setClassLoader(ClassLoader JavaDoc classLoader) {
1428        this.classLoader = classLoader;
1429    }
1430    
1431    /**
1432     * Turn on or off the XML Validation for all standard deployment
1433     * descriptors loading
1434     * @param true to turn on XML validation
1435     */

1436     public void setXMLValidation(boolean validate) {
1437     isValidatingXML=validate;
1438     }
1439     
1440     /**
1441      * @return true if the Deployment Descriptors XML will be validated
1442      * while reading.
1443      */

1444    public boolean getXMLValidation() {
1445    return isValidatingXML;
1446    }
1447
1448    /**
1449     * Turn on or off the XML Validation for runtime deployment
1450     * descriptors loading
1451     * @param true to turn on XML validation
1452     */

1453     public void setRuntimeXMLValidation(boolean validate) {
1454         isValidatingRuntimeXML = validate;
1455     }
1456
1457     /**
1458      * @return true if the runtime XML will be validated
1459      * while reading.
1460      */

1461    public boolean getRuntimeXMLValidation() {
1462        return isValidatingRuntimeXML;
1463    }
1464
1465    /**
1466     * Sets the xml validation error reporting/recovering level.
1467     * The reporting level is active only when xml validation is
1468     * turned on @see setXMLValidation.
1469     * so far, two values can be passed, medium which reports the
1470     * xml validation and continue and full which reports the
1471     * xml validation and stop the xml parsing.
1472     */

1473     public void setXMLValidationLevel(String JavaDoc level) {
1474     validationLevel = level;
1475     }
1476     
1477     /**
1478      * @return the xml validation reporting level
1479      */

1480      public String JavaDoc getXMLValidationLevel() {
1481      return validationLevel;
1482      }
1483
1484    /**
1485     * Sets the runtime xml validation error reporting/recovering level.
1486     * The reporting level is active only when xml validation is
1487     * turned on @see setXMLValidation.
1488     * so far, two values can be passed, medium which reports the
1489     * xml validation and continue and full which reports the
1490     * xml validation and stop the xml parsing.
1491     */

1492     public void setRuntimeXMLValidationLevel(String JavaDoc level) {
1493         runtimeValidationLevel = level;
1494     }
1495     
1496     /**
1497      * @return the runtime xml validation reporting level
1498      */

1499      public String JavaDoc getRuntimeXMLValidationLevel() {
1500          return runtimeValidationLevel;
1501      }
1502    
1503    /**
1504     * validates the DOL Objects associated with this archivist, usually
1505     * it requires that a class loader being set on this archivist or passed
1506     * as a parameter
1507     */

1508    public void validate(ClassLoader JavaDoc aClassLoader) {
1509    }
1510    
1511    /**
1512     * Copy this archivist to a new abstract archive
1513     * @param out the new archive to use to copy our contents into
1514     */

1515    public void copyInto(AbstractArchive target) throws IOException {
1516        AbstractArchive source = abstractArchiveFactory.openArchive(path);
1517        copyInto(source, target);
1518    }
1519    
1520    /**
1521     * Copy source archivist to a target abstract archive. By default,
1522     * every entry in source archive will be copied to the target archive,
1523     * including the manifest of the source archive.
1524     * @param source the source archive to copy from
1525     * @param target the target archive to copy to
1526     * @param entriesToSkip the entries that will be skipped by target archive
1527     */

1528    public void copyInto(AbstractArchive source, AbstractArchive target) throws IOException {
1529        copyInto(source, target, null, true);
1530    }
1531
1532    /**
1533     * Copy source archivist to a target abstract archive. By default,
1534     * every entry in source archive will be copied to the target archive.
1535     * @param source the source archive to copy from
1536     * @param target the target archive to copy to
1537     * @param overwriteManifest if true, the manifest in source archive
1538     * overwrites the one in target archive
1539     */

1540    public void copyInto(AbstractArchive source, AbstractArchive target, boolean overwriteManifest) throws IOException {
1541        copyInto(source, target, null, overwriteManifest);
1542    }
1543
1544    /**
1545     * Copy source archivist to a target abstract archive. By default, the manifest
1546     * in source archive overwrites the one in target archive.
1547     * @param source the source archive to copy from
1548     * @param target the target archive to copy to
1549     * @param entriesToSkip the entries that will be skipped by target archive
1550     */

1551    public void copyInto(AbstractArchive source, AbstractArchive target, Vector entriesToSkip)
1552        throws IOException {
1553        copyInto(source, target, entriesToSkip, true);
1554    }
1555    
1556    /**
1557     * Copy this archivist to a new abstract archive
1558     * @param source the source archive to copy from
1559     * @param target the target archive to copy to
1560     * @param entriesToSkip the entries that will be skipped by target archive
1561     * @param overwriteManifest if true, the manifest in source archive
1562     * overwrites the one in target archive
1563     */

1564    public void copyInto(AbstractArchive source, AbstractArchive target,
1565                         Vector entriesToSkip, boolean overwriteManifest)
1566        throws IOException {
1567            
1568        copyJarElements(source, target, entriesToSkip);
1569        if (overwriteManifest) {
1570            Manifest m = source.getManifest();
1571            if (m != null) {
1572                OutputStream os = target.putNextEntry(JarFile.MANIFEST_NAME);
1573                m.write(os);
1574                target.closeEntry();
1575            }
1576        }
1577    }
1578    
1579    /**
1580     * extract a entry of this archive to a file
1581     * @param the entry name
1582     * @param the file to copy the entry into
1583     */

1584    public void extractEntry(String JavaDoc entryName, File out) throws IOException {
1585        AbstractArchive archive = abstractArchiveFactory.openArchive(path);
1586        InputStream is = archive.getEntry(entryName);
1587        OutputStream os = new BufferedOutputStream(new FileOutputStream(out));
1588        ArchivistUtils.copy(new BufferedInputStream(is), os);
1589        archive.close();
1590    }
1591    
1592    /**
1593     * Sets the pluggable archivist factory for this instance
1594     */

1595    public void setPluggableArchivists(PluggableArchivists pa) {
1596        this.pa = pa;
1597    }
1598    
1599    /**
1600     * @return the pluggable archivist factory
1601     */

1602    public PluggableArchivists getPluggableArchivists() {
1603        if (pa==null) {
1604            return ArchivistFactory.getPluggableArchivists();
1605        } else {
1606            return pa;
1607        }
1608    }
1609
1610    public static void copyAnEntry(AbstractArchive in,
1611        AbstractArchive out, String JavaDoc entryName) throws IOException {
1612        InputStream is = null;
1613        InputStream is2 = null;
1614        try {
1615            is = in.getEntry(entryName);
1616            is2 = out.getEntry(entryName);
1617            if (is != null && is2 == null) {
1618                OutputStream os = out.putNextEntry(entryName);
1619                ArchivistUtils.copyWithoutClose(is, os);
1620            }
1621        } finally {
1622            /*
1623             *Close any streams that were opened.
1624             */

1625            if (is != null) {
1626                is.close();
1627            }
1628            if (is2 != null) {
1629                is2.close();
1630            }
1631            out.closeEntry();
1632        }
1633    }
1634
1635    public void copyStandardDeploymentDescriptors(AbstractArchive in,
1636        AbstractArchive out) throws IOException {
1637        String JavaDoc entryName = getDeploymentDescriptorPath();
1638        copyAnEntry(in, out, entryName);
1639        
1640        Descriptor desc = getDescriptor();
1641
1642        // only bundle descriptor can have web services
1643
if (desc instanceof BundleDescriptor) {
1644            BundleDescriptor desc2 = (BundleDescriptor)desc;
1645            if (desc2.hasWebServices()) {
1646                DeploymentDescriptorFile webServicesDD =
1647                    getWebServicesDDFile((BundleDescriptor)desc2);
1648                String JavaDoc anEntry = webServicesDD.getDeploymentDescriptorPath();
1649                copyAnEntry(in, out, anEntry);
1650            }
1651        }
1652    }
1653
1654    // copy wsdl and mapping files etc
1655
public static void copyExtraElements(AbstractArchive in,
1656        AbstractArchive out) throws IOException {
1657        Enumeration entries = in.entries();
1658        if (entries!=null) {
1659            for (;entries.hasMoreElements();) {
1660                String JavaDoc anEntry = (String JavaDoc) entries.nextElement();
1661                if(anEntry.endsWith(PERSISTENCE_DD_ENTRY)) {
1662                    // Don't copy persistence.xml file because they are some times
1663
// bundled inside war/WEB-INF/lib/*.jar and hence we always
1664
// read them from exploded directory.
1665
// see Integration Notice #80587
1666
continue;
1667                }
1668                if (anEntry.indexOf(WSDL) != -1 ||
1669                    anEntry.indexOf(XML) != -1 ||
1670                    anEntry.indexOf(XSD) != -1) {
1671                    copyAnEntry(in, out, anEntry);
1672                }
1673            }
1674        }
1675     }
1676
1677    protected void readPersistenceDeploymentDescriptor(
1678            Archive subArchive, String JavaDoc puRoot, Descriptor descriptor)
1679            throws IOException, SAXParseException JavaDoc {
1680        final String JavaDoc subArchiveURI = AbstractArchive.class.cast(subArchive).getArchiveUri();
1681        if (logger.isLoggable(Level.FINE)) {
1682            logger.logp(Level.FINE, "Archivist",
1683                    "readPersistenceDeploymentDescriptor",
1684                    "PURoot = [{0}] subArchive = {1}",
1685                    new Object JavaDoc[]{puRoot, subArchiveURI});
1686        }
1687        final RootDeploymentDescriptor rootDD =
1688                RootDeploymentDescriptor.class.cast(descriptor);
1689        if (rootDD.getPersistenceUnitsDescriptor(puRoot) != null) {
1690            if (logger.isLoggable(Level.FINE)) {
1691                logger.logp(Level.FINE, "Archivist",
1692                        "readPersistenceDeploymentDescriptor",
1693                        "PU has been already read for = {0}",
1694                        subArchiveURI);
1695            }
1696            return;
1697        }
1698        PersistenceDeploymentDescriptorFile persistenceDeploymentDescriptorFile
1699                = new PersistenceDeploymentDescriptorFile();
1700        persistenceDeploymentDescriptorFile.setErrorReportingString(
1701                subArchiveURI.toString());
1702        persistenceDeploymentDescriptorFile.setXMLValidation(getXMLValidation());
1703        persistenceDeploymentDescriptorFile.setXMLValidationLevel(
1704                getXMLValidationLevel());
1705        InputStream is = subArchive.getEntry(
1706                persistenceDeploymentDescriptorFile.getDeploymentDescriptorPath());
1707        if (is == null) {
1708            if (logger.isLoggable(Level.FINE)) {
1709                logger.logp(Level.FINE, "Archivist",
1710                    "readPersistenceDeploymentDescriptor",
1711                    "{0} does not contain {1}, so it is not a PU Root.",
1712                    new Object JavaDoc[]{subArchiveURI,
1713                                 persistenceDeploymentDescriptorFile.getDeploymentDescriptorPath()});
1714            }
1715            return;
1716        }
1717        try {
1718            PersistenceUnitsDescriptor persistenceUnitsDescriptor =
1719                    PersistenceUnitsDescriptor.class.cast(
1720                            persistenceDeploymentDescriptorFile.read(rootDD, is));
1721            rootDD.addPersistenceUnitsDescriptor(puRoot,
1722                    persistenceUnitsDescriptor);
1723        } finally {
1724            is.close();
1725        }
1726    }
1727}
1728
Popular Tags