| /* Copyright 2004 The Apache Software Foundation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.xmlbeans.impl.tool; |
| |
| import org.apache.xmlbeans.SchemaTypeSystem; |
| import org.apache.xmlbeans.SystemProperties; |
| import org.apache.xmlbeans.impl.util.FilerImpl; |
| import org.apache.xmlbeans.XmlOptions; |
| import org.apache.xmlbeans.Filer; |
| import org.apache.xmlbeans.impl.repackage.Repackager; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| |
| public class SchemaCodeGenerator |
| { |
| /** |
| * Saves a SchemaTypeSystem to the specified directory. |
| * |
| * @param system the <code>SchemaTypeSystem</code> to save |
| * @param classesDir the destination directory for xsb's |
| * @param sourceFile if present, the TypeSystemHolder source will be |
| * generated in this file for subsequent compilation, |
| * if null then the source will be generated in a temp |
| * directory and then compiled to the destination dir |
| * @param repackager the repackager to use when generating the holder class |
| * @param options options. Can be null |
| * @deprecated Use {@link SchemaTypeSystem.save()} instead. |
| */ |
| public static void saveTypeSystem(SchemaTypeSystem system, File classesDir, |
| File sourceFile, Repackager repackager, XmlOptions options) |
| throws IOException |
| { |
| Filer filer = new FilerImpl(classesDir, null, repackager, false, false); |
| system.save(filer); |
| } |
| |
| static void deleteObsoleteFiles(File rootDir, File srcDir, Set seenFiles) |
| { |
| if (!(rootDir.isDirectory() && srcDir.isDirectory())) |
| throw new IllegalArgumentException(); |
| String absolutePath = srcDir.getAbsolutePath(); |
| // Do a sanity check to make sure we don't delete by mistake some important dir |
| if (absolutePath.length() <= 5) |
| return; |
| if (absolutePath.startsWith("/home/") && |
| (absolutePath.indexOf("/", 6) >= absolutePath.length() - 1 || |
| absolutePath.indexOf("/", 6) < 0)) |
| return; |
| |
| // Go recursively starting with srcDir and delete all files that are |
| // not in the given Set |
| File[] files = srcDir.listFiles(); |
| for (int i = 0; i < files.length; i++) |
| { |
| if (files[i].isDirectory()) |
| deleteObsoleteFiles(rootDir, files[i], seenFiles); |
| else if (seenFiles.contains(files[i])) |
| ; |
| else |
| { |
| deleteXmlBeansFile(files[i]); |
| deleteDirRecursively(rootDir, files[i].getParentFile()); |
| } |
| } |
| } |
| |
| private static void deleteXmlBeansFile(File file) |
| { |
| if (file.getName().endsWith(".java")) |
| file.delete(); |
| } |
| |
| private static void deleteDirRecursively(File root, File dir) |
| { |
| String[] list = dir.list(); |
| while (list != null && list.length == 0 && !dir.equals(root)) |
| { |
| dir.delete(); |
| dir = dir.getParentFile(); |
| list = dir.list(); |
| } |
| } |
| |
| protected static File createTempDir() throws IOException |
| { |
| |
| // Some beta builds of JDK1.5 are having troubles creating temp directories |
| // if the java.io.tmpdir doesn't exist. This seems to help. |
| try { |
| File tmpDirFile = new File(SystemProperties.getProperty("java.io.tmpdir")); |
| tmpDirFile.mkdirs(); |
| } catch(Exception e) { e.printStackTrace(); } |
| |
| File tmpFile = File.createTempFile("xbean", null); |
| String path = tmpFile.getAbsolutePath(); |
| if (!path.endsWith(".tmp")) |
| throw new IOException("Error: createTempFile did not create a file ending with .tmp"); |
| path = path.substring(0, path.length() - 4); |
| File tmpSrcDir = null; |
| |
| for (int count = 0; count < 100; count++) |
| { |
| String name = path + ".d" + (count == 0 ? "" : Integer.toString(count++)); |
| |
| tmpSrcDir = new File(name); |
| |
| if (!tmpSrcDir.exists()) |
| { |
| boolean created = tmpSrcDir.mkdirs(); |
| assert created : "Could not create " + tmpSrcDir.getAbsolutePath(); |
| break; |
| } |
| } |
| tmpFile.deleteOnExit(); |
| |
| return tmpSrcDir; |
| } |
| |
| protected static void tryHardToDelete(File dir) |
| { |
| tryToDelete(dir); |
| if (dir.exists()) |
| tryToDeleteLater(dir); |
| } |
| |
| private static void tryToDelete(File dir) |
| { |
| if (dir.exists()) |
| { |
| if (dir.isDirectory()) |
| { |
| String[] list = dir.list(); // can return null if I/O error |
| if (list != null) |
| for (int i = 0; i < list.length; i++) |
| tryToDelete(new File(dir, list[i])); |
| } |
| if (!dir.delete()) |
| return; // don't try very hard, because we're just deleting tmp |
| } |
| } |
| |
| private static Set deleteFileQueue = new HashSet(); |
| private static int triesRemaining = 0; |
| |
| private static boolean tryNowThatItsLater() |
| { |
| List files; |
| |
| synchronized (deleteFileQueue) |
| { |
| files = new ArrayList(deleteFileQueue); |
| deleteFileQueue.clear(); |
| } |
| |
| List retry = new ArrayList(); |
| |
| for (Iterator i = files.iterator(); i.hasNext(); ) |
| { |
| File file = (File)i.next(); |
| tryToDelete(file); |
| if (file.exists()) |
| retry.add(file); |
| } |
| |
| synchronized (deleteFileQueue) |
| { |
| if (triesRemaining > 0) |
| triesRemaining -= 1; |
| |
| if (triesRemaining <= 0 || retry.size() == 0) // done? |
| triesRemaining = 0; |
| else |
| deleteFileQueue.addAll(retry); // try again? |
| |
| return (triesRemaining <= 0); |
| } |
| } |
| |
| private static void giveUp() |
| { |
| synchronized (deleteFileQueue) |
| { |
| deleteFileQueue.clear(); |
| triesRemaining = 0; |
| } |
| } |
| |
| private static void tryToDeleteLater(File dir) |
| { |
| synchronized (deleteFileQueue) |
| { |
| deleteFileQueue.add(dir); |
| if (triesRemaining == 0) |
| { |
| new Thread() |
| { |
| public void run() |
| { |
| // repeats tryNow until triesRemaining == 0 |
| try |
| { |
| for (;;) |
| { |
| if (tryNowThatItsLater()) |
| return; // succeeded |
| Thread.sleep(1000 * 3); // wait three seconds |
| } |
| } |
| catch (InterruptedException e) |
| { |
| giveUp(); |
| } |
| } |
| }; |
| } |
| |
| if (triesRemaining < 10) |
| triesRemaining = 10; |
| } |
| } |
| |
| } |