Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/objectstyle/cayenne/project/ProjectConfigurator.java


1   /* ====================================================================
2    * 
3    * The ObjectStyle Group Software License, Version 1.0 
4    *
5    * Copyright (c) 2002-2003 The ObjectStyle Group 
6    * and individual authors of the software.  All rights reserved.
7    *
8    * Redistribution and use in source and binary forms, with or without
9    * modification, are permitted provided that the following conditions
10   * are met:
11   *
12   * 1. Redistributions of source code must retain the above copyright
13   *    notice, this list of conditions and the following disclaimer. 
14   *
15   * 2. Redistributions in binary form must reproduce the above copyright
16   *    notice, this list of conditions and the following disclaimer in
17   *    the documentation and/or other materials provided with the
18   *    distribution.
19   *
20   * 3. The end-user documentation included with the redistribution, if
21   *    any, must include the following acknowlegement:  
22   *       "This product includes software developed by the 
23   *        ObjectStyle Group (http://objectstyle.org/)."
24   *    Alternately, this acknowlegement may appear in the software itself,
25   *    if and wherever such third-party acknowlegements normally appear.
26   *
27   * 4. The names "ObjectStyle Group" and "Cayenne" 
28   *    must not be used to endorse or promote products derived
29   *    from this software without prior written permission. For written 
30   *    permission, please contact andrus@objectstyle.org.
31   *
32   * 5. Products derived from this software may not be called "ObjectStyle"
33   *    nor may "ObjectStyle" appear in their names without prior written
34   *    permission of the ObjectStyle Group.
35   *
36   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39   * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
40   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47   * SUCH DAMAGE.
48   * ====================================================================
49   *
50   * This software consists of voluntary contributions made by many
51   * individuals on behalf of the ObjectStyle Group.  For more
52   * information on the ObjectStyle Group, please see
53   * <http://objectstyle.org/>.
54   *
55   */
56  package org.objectstyle.cayenne.project;
57  
58  import java.io.File;
59  import java.io.IOException;
60  import java.util.Iterator;
61  
62  import org.apache.log4j.Logger;
63  import org.objectstyle.cayenne.conf.Configuration;
64  import org.objectstyle.cayenne.util.Util;
65  import org.objectstyle.cayenne.util.ZipUtil;
66  
67  /**
68   * Performs on the fly reconfiguration of Cayenne projects.
69   *  
70   * @author Andrei Adamchik
71   */
72  public class ProjectConfigurator {
73      private static Logger logObj = Logger.getLogger(ProjectConfigurator.class);
74      protected ProjectConfigInfo info;
75  
76      public ProjectConfigurator(ProjectConfigInfo info) {
77          this.info = info;
78      }
79  
80      /**
81       * Performs reconfiguration of the project.
82       * 
83       * @throws ProjectException
84       */
85      public void execute() throws ProjectException {
86          File tmpDir = null;
87          File tmpDest = null;
88          try {
89              // initialize default settings 
90              if (info.getDestJar() == null) {
91                  info.setDestJar(info.getSourceJar());
92              }
93  
94              // sanity check
95              validate();
96  
97              // do the processing
98              tmpDir = makeTempDirectory();
99              ZipUtil.unzip(info.getSourceJar(), tmpDir);
100 
101             reconfigureProject(tmpDir);
102 
103             tmpDest = makeTempDestJar();
104             ZipUtil.zip(tmpDest, tmpDir, tmpDir.listFiles(), '/');
105 
106             // finally, since everything goes well so far, rename temp file to final name
107             if (info.getDestJar().exists() && !info.getDestJar().delete()) {
108                 throw new IOException(
109                     "Can't delete old jar file: " + info.getDestJar());
110             }
111 
112             if (!tmpDest.renameTo(info.getDestJar())) {
113                 throw new IOException(
114                     "Error renaming: " + tmpDest + " to " + info.getDestJar());
115             }
116         } catch (IOException ex) {
117             throw new ProjectException("Error performing reconfiguration.", ex);
118         } finally {
119             if (tmpDir != null) {
120                 cleanup(tmpDir);
121             }
122 
123             if (tmpDest != null) {
124                 tmpDest.delete();
125             }
126         }
127     }
128 
129     /**
130      * Performs reconfiguration of the unjarred project.
131      * 
132      * @param projectDir a directory where a working copy of the project is
133      * located.
134      */
135     protected void reconfigureProject(File projectDir)
136         throws ProjectException {
137         File projectFile = new File(projectDir, Configuration.DEFAULT_DOMAIN_FILE);
138 
139         // process alternative project file
140         if (info.getAltProjectFile() != null) {
141             if (!Util.copy(info.getAltProjectFile(), projectFile)) {
142                 throw new ProjectException(
143                     "Can't copy project file: " + info.getAltProjectFile());
144             }
145         }
146 
147         // copy driver files, delete unused
148         Iterator it = info.getNodes().iterator();
149         boolean needFix = it.hasNext();
150         while (it.hasNext()) {
151             DataNodeConfigInfo nodeInfo = (DataNodeConfigInfo) it.next();
152             String name = nodeInfo.getName();
153 
154             File targetDriverFile =
155                 new File(projectDir, name + DataNodeFile.LOCATION_SUFFIX);
156 
157             // these are the two cases when the driver file must be deleted
158             if (nodeInfo.getDataSource() != null
159                 || nodeInfo.getDriverFile() != null) {
160                 if (targetDriverFile.exists()) {
161                     targetDriverFile.delete();
162                 }
163             }
164 
165             if (nodeInfo.getDriverFile() != null
166                 && !nodeInfo.getDriverFile().equals(targetDriverFile)) {
167                 // need to copy file from another location
168                 if (!Util.copy(nodeInfo.getDriverFile(), targetDriverFile)) {
169                     throw new ProjectException(
170                         "Can't copy driver file from "
171                             + nodeInfo.getDriverFile());
172                 }
173             }
174         }
175 
176         // load project
177         if (needFix) {
178             // read the project and fix data nodes
179             PartialProject project = new PartialProject(projectFile);
180             project.updateNodes(info.getNodes());
181             project.save();
182         }
183     }
184 
185     /**
186      * Returns a temporary file for the destination jar.
187      */
188     protected File makeTempDestJar() throws IOException {
189         File destFolder = info.getDestJar().getParentFile();
190         if (destFolder != null && !destFolder.isDirectory()) {
191             if (!destFolder.mkdirs()) {
192                 throw new IOException(
193                     "Can't create directory: " + destFolder.getCanonicalPath());
194             }
195         }
196 
197         String baseName = "tmp_" + info.getDestJar().getName();
198 
199         // seeting upper limit on a number of tries, though normally we would expect
200         // to succeed from the first attempt...
201         for (int i = 0; i < 50; i++) {
202             File tmpFile =
203                 (destFolder != null)
204                     ? new File(destFolder, baseName + i)
205                     : new File(baseName + i);
206             if (!tmpFile.exists()) {
207                 return tmpFile;
208             }
209         }
210 
211         throw new IOException("Problems creating temporary file.");
212     }
213 
214     /**
215      *  Deletes a temporary directories and files created.
216      */
217     protected void cleanup(File dir) {
218         if (!Util.delete(dir.getPath(), true)) {
219             logObj.info("Can't delete temporary directory: " + dir);
220         }
221     }
222 
223     /**
224      * Creates a temporary directory to unjar the jar file.
225      * 
226      * @return File
227      * @throws IOException
228      */
229     protected File makeTempDirectory() throws IOException {
230         File destFolder = info.getDestJar().getParentFile();
231         if (destFolder != null && !destFolder.isDirectory()) {
232             if (!destFolder.mkdirs()) {
233                 throw new IOException(
234                     "Can't create directory: " + destFolder.getCanonicalPath());
235             }
236         }
237 
238         String baseName = info.getDestJar().getName();
239         if (baseName.endsWith(".jar")) {
240             baseName = baseName.substring(0, baseName.length() - 4);
241         }
242 
243         // seeting upper limit on a number of tries, though normally we would expect
244         // to succeed from the first attempt... 
245         for (int i = 0; i < 50; i++) {
246             File tmpDir =
247                 (destFolder != null)
248                     ? new File(destFolder, baseName + i)
249                     : new File(baseName + i);
250             if (!tmpDir.exists()) {
251                 if (!tmpDir.mkdir()) {
252                     throw new IOException(
253                         "Can't create directory: " + tmpDir.getCanonicalPath());
254                 }
255 
256                 return tmpDir;
257             }
258         }
259 
260         throw new IOException("Problems creating temporary directory.");
261     }
262 
263     /**
264      * Validates consistency of the reconfiguration information.
265      */
266     protected void validate() throws IOException, ProjectException {
267         if (info == null) {
268             throw new ProjectException("ProjectConfig info is not set.");
269         }
270 
271         if (info.getSourceJar() == null) {
272             throw new ProjectException("Source jar file is not set.");
273         }
274 
275         if (!info.getSourceJar().isFile()) {
276             throw new IOException(info.getSourceJar() + " is not a file.");
277         }
278 
279         if (!info.getSourceJar().canRead()) {
280             throw new IOException("Can't read file: " + info.getSourceJar());
281         }
282     }
283 }