001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.jbi.util;
018
019 import java.io.File;
020 import java.io.IOException;
021
022 import org.apache.commons.logging.Log;
023 import org.apache.commons.logging.LogFactory;
024
025 /**
026 * Supports a simple versioning scheme using the file system
027 *
028 * @version $Revision: 564607 $
029 */
030 public final class FileVersionUtil {
031
032 private static final Log LOG = LogFactory.getLog(FileVersionUtil.class);
033
034 private static final String VERSION_PREFIX = "version_";
035
036 private static final String[] RESERVED = {VERSION_PREFIX };
037
038 private FileVersionUtil() {
039 }
040
041 /**
042 * Get the latest version number for a directory
043 *
044 * @param rootDirectory
045 * @return the version number
046 */
047 public static int getLatestVersionNumber(File rootDirectory) {
048 int result = -1;
049 if (isVersioned(rootDirectory)) {
050 File[] files = rootDirectory.listFiles();
051 for (int i = 0; i < files.length; i++) {
052 int version = getVersionNumber(files[i].getName());
053 if (version > result) {
054 result = version;
055 }
056 }
057 }
058 return result;
059 }
060
061 /**
062 * Get the latest versioned directory
063 *
064 * @param rootDirectory
065 * @return the directory
066 * @throws IOException
067 */
068 public static File getLatestVersionDirectory(File rootDirectory) {
069 File result = null;
070 int highestVersion = -1;
071 if (rootDirectory != null && isVersioned(rootDirectory)) {
072 File[] files = rootDirectory.listFiles();
073 for (int i = 0; i < files.length; i++) {
074 int version = getVersionNumber(files[i].getName());
075 if (version > highestVersion) {
076 highestVersion = version;
077 result = files[i];
078 }
079 }
080 }
081 return result;
082 }
083
084 /**
085 * Create a new version directory
086 *
087 * @param rootDirectory
088 * @return the created version directory
089 * @throws IOException
090 */
091 public static File createNewVersionDirectory(File rootDirectory) throws IOException {
092 File result = getNewVersionDirectory(rootDirectory);
093 if (!FileUtil.buildDirectory(result)) {
094 throw new IOException("Failed to build version directory: " + result);
095 }
096 return result;
097 }
098
099 /**
100 * get's the new version file - without creating the directory
101 *
102 * @param rootDirectory
103 * @return the version directory
104 * @throws IOException
105 */
106 public static File getNewVersionDirectory(File rootDirectory) throws IOException {
107 File result = null;
108 if (FileUtil.buildDirectory(rootDirectory)) {
109 String versionDirectoryName = VERSION_PREFIX;
110 if (isVersioned(rootDirectory)) {
111 int versionNumber = getLatestVersionNumber(rootDirectory);
112 versionNumber = versionNumber > 0 ? versionNumber + 1 : 1;
113 versionDirectoryName += versionNumber;
114 } else {
115 versionDirectoryName += 1;
116 }
117 result = FileUtil.getDirectoryPath(rootDirectory, versionDirectoryName);
118 } else {
119 throw new IOException("Cannot build parent directory: " + rootDirectory);
120 }
121 return result;
122 }
123
124 /**
125 * Used to move non-version files/directories to versioned
126 *
127 * @param rootDirectory
128 * @throws IOException
129 */
130 public static void initializeVersionDirectory(File rootDirectory) throws IOException {
131 if (!isVersioned(rootDirectory)) {
132 File newRoot = createNewVersionDirectory(rootDirectory);
133 File[] files = rootDirectory.listFiles();
134 for (int i = 0; i < files.length; i++) {
135 if (!isReserved(files[i].getName())) {
136 LOG.info(rootDirectory.getPath() + ": moving non-versioned file " + files[i].getName() + " to " + newRoot.getName());
137 File moveTo = FileUtil.getDirectoryPath(newRoot, files[i].getName());
138 FileUtil.moveFile(files[i], moveTo);
139 }
140 }
141 }
142 }
143
144 private static boolean isVersioned(File rootDirectory) {
145 boolean result = false;
146 if (rootDirectory.exists() && rootDirectory.isDirectory()) {
147 File[] files = rootDirectory.listFiles();
148 result = files == null || files.length == 0;
149 if (!result) {
150 for (int i = 0; i < files.length; i++) {
151 if (isReserved(files[i].getName())) {
152 result = true;
153 break;
154 }
155 }
156 }
157 }
158 return result;
159 }
160
161 private static boolean isReserved(String name) {
162 boolean result = false;
163 if (name != null) {
164 for (int i = 0; i < RESERVED.length; i++) {
165 if (name.startsWith(RESERVED[i])) {
166 result = true;
167 break;
168 }
169 }
170 }
171 return result;
172 }
173
174 private static int getVersionNumber(String name) {
175 int result = -1;
176 if (name != null && name.startsWith(VERSION_PREFIX)) {
177 String number = name.substring(VERSION_PREFIX.length());
178 result = Integer.parseInt(number);
179 }
180 return result;
181 }
182 }