001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020 021 package org.apache.geronimo.system.plugin; 022 023 import java.io.File; 024 import java.io.IOException; 025 import java.util.ArrayList; 026 import java.util.HashMap; 027 import java.util.List; 028 import java.util.Map; 029 030 import org.apache.geronimo.gbean.GBeanInfo; 031 import org.apache.geronimo.gbean.GBeanInfoBuilder; 032 import org.apache.geronimo.kernel.config.IOUtil; 033 import org.apache.geronimo.kernel.repository.Artifact; 034 import org.apache.geronimo.system.serverinfo.ServerInfo; 035 import org.codehaus.plexus.archiver.Archiver; 036 import org.codehaus.plexus.archiver.ArchiverException; 037 import org.codehaus.plexus.archiver.UnixStat; 038 import org.codehaus.plexus.archiver.tar.TarArchiver; 039 import org.codehaus.plexus.archiver.tar.TarLongFileMode; 040 import org.codehaus.plexus.archiver.zip.ZipArchiver; 041 //maven inconsistency -- if we can use 1.0-alpha-9 uncomment 042 //import org.codehaus.plexus.archiver.util.DefaultFileSet; 043 044 /** 045 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 046 */ 047 public class ArchiverGBean implements ServerArchiver { 048 049 private final ServerInfo serverInfo; 050 051 private List<String> excludes = new ArrayList<String>(); 052 053 public ArchiverGBean(ServerInfo serverInfo) { 054 this.serverInfo = serverInfo; 055 } 056 057 public void addExclude(String pattern) { 058 this.excludes.add(pattern); 059 } 060 061 public void removeExclude(String pattern) { 062 this.excludes.remove(pattern); 063 } 064 065 private void removeExcludes(File source, Map<String, File> all) { 066 Map<String, File> matches = new HashMap<String, File>(); 067 for (String exclude : this.excludes) { 068 IOUtil.find(source, exclude, matches); 069 } 070 071 for (String exclude : matches.keySet()) { 072 all.remove(exclude); 073 } 074 } 075 076 public File archive(String sourcePath, String destPath, Artifact artifact) throws ArchiverException, IOException { 077 File source = serverInfo.resolve(sourcePath); 078 File dest = serverInfo.resolve(destPath); 079 String serverName = artifact.getArtifactId() + "-" + artifact.getVersion(); 080 dest = new File(dest, serverName + "-bin." + artifact.getType()); 081 Archiver archiver; 082 if ("tar.gz".equals(artifact.getType())) { 083 archiver = new TarArchiver(); 084 TarArchiver.TarCompressionMethod tarCompressionMethod = new TarArchiver.TarCompressionMethod(); 085 tarCompressionMethod.setValue("gzip"); 086 ((TarArchiver) archiver).setCompression(tarCompressionMethod); 087 TarLongFileMode fileMode = new TarLongFileMode(); 088 fileMode.setValue(TarLongFileMode.GNU); 089 ((TarArchiver) archiver).setLongfile(fileMode); 090 } else if ("zip".equals(artifact.getType())) { 091 archiver = new ZipArchiver(); 092 } else { 093 throw new IllegalArgumentException("Unknown target type: " + artifact.getType()); 094 } 095 archiver.setIncludeEmptyDirs(true); 096 archiver.setDestFile(dest); 097 /* see if using plexus-archiver 1.0-alpha-7 same as maven lets us share code. Following is for 1.0-alpha-9 098 DefaultFileSet all = new DefaultFileSet(); 099 all.setDirectory(source); 100 archiver.addFileSet(all); 101 */ 102 103 // add in all files and mark them with default file permissions 104 Map<File, Boolean> emptyDirs = new HashMap<File, Boolean>(); 105 Map<String, File> all = IOUtil.listAllFileNames(source); 106 removeExcludes(source, all); 107 for (Map.Entry<String, File> entry : all.entrySet()) { 108 String destFileName = serverName + "/" + entry.getKey(); 109 File sourceFile = entry.getValue(); 110 if (sourceFile.isFile()) { 111 archiver.addFile(sourceFile, destFileName, UnixStat.DEFAULT_FILE_PERM); 112 // mark parent directories non-empty 113 for (File parentDir = sourceFile.getParentFile(); 114 parentDir != null && !parentDir.equals(source); 115 parentDir = parentDir.getParentFile()) { 116 emptyDirs.put(parentDir, Boolean.FALSE); 117 } 118 119 } else if (sourceFile.isDirectory()) { 120 Boolean isEmpty = emptyDirs.get(sourceFile); 121 if (isEmpty == null) { 122 emptyDirs.put(sourceFile, Boolean.TRUE); 123 // mark parent directories non-empty 124 for (File parentDir = sourceFile.getParentFile(); 125 parentDir != null && !parentDir.equals(source); 126 parentDir = parentDir.getParentFile()) { 127 emptyDirs.put(parentDir, Boolean.FALSE); 128 } 129 } 130 } 131 } 132 133 if (!all.isEmpty()) { 134 emptyDirs.put(source, Boolean.FALSE); 135 } 136 137 String sourceDirPath = source.getAbsolutePath(); 138 for (Map.Entry<File, Boolean> entry : emptyDirs.entrySet()) { 139 if (entry.getValue().booleanValue()) { 140 String emptyDirPath = entry.getKey().getAbsolutePath(); 141 String relativeDir = emptyDirPath.substring(sourceDirPath.length()); 142 relativeDir = relativeDir.replace('\\', '/'); 143 archiver.addDirectory(entry.getKey(), serverName + relativeDir); 144 } 145 } 146 emptyDirs.clear(); 147 148 all.clear(); 149 150 // add execute permissions to all non-batch files in the bin/ directory 151 File bin = new File(source, "bin"); 152 if (bin.exists()) { 153 Map<String, File> includes = IOUtil.listAllFileNames(bin); 154 for (Map.Entry<String, File> entry : includes.entrySet()) { 155 String destFileName = serverName + "/bin/" + entry.getKey(); 156 File sourceFile = entry.getValue(); 157 if (!destFileName.endsWith(".bat") && sourceFile.isFile()) { 158 archiver.addFile(sourceFile, destFileName, UnixStat.DEFAULT_DIR_PERM); 159 } 160 } 161 } 162 163 archiver.createArchive(); 164 return dest; 165 } 166 167 public static final GBeanInfo GBEAN_INFO; 168 169 static { 170 GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(ArchiverGBean.class); 171 infoFactory.addReference("ServerInfo", ServerInfo.class, "GBean"); 172 173 infoFactory.setConstructor(new String[]{"ServerInfo"}); 174 175 GBEAN_INFO = infoFactory.getBeanInfo(); 176 } 177 178 public static GBeanInfo getGBeanInfo() { 179 return GBEAN_INFO; 180 } 181 182 }