/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.openejb.maven.plugin.customizer.monkey.index; import org.apache.openejb.loader.JarLocation; import org.apache.openejb.maven.plugin.customizer.monkey.classloader.ClassLoaderFactory; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.TreeMap; import static java.util.Arrays.asList; public class FileIndexer { private final ClassLoader loader; private final File binaries; private final String binaryRoot; private final String ignore; private final ClassLoaderFactory loaderFactory = new ClassLoaderFactory(); private final Map<File, List<Item>> index = new TreeMap<File, List<Item>>(); private final List<String> filesToRemove; public FileIndexer(final File base, final File patchedFilesFolder, final Properties configuration, final String ignore) { this.binaries = patchedFilesFolder; try { final String path = patchedFilesFolder.getCanonicalFile().getAbsolutePath(); this.binaryRoot = path + (path.endsWith(File.separator) ? "" : File.separator); } catch (final IOException e) { throw new IllegalArgumentException(e); } final File libs = new File(base, "lib"); if (!libs.isDirectory()) { throw new IllegalArgumentException("lib folder not found"); } this.loader = loaderFactory.create(libs); final String toRemove = configuration.getProperty("remove"); this.filesToRemove = toRemove == null ? Collections.<String>emptyList() : new ArrayList<String>(asList(toRemove.split(" *, *"))); this.ignore = ignore; } public Map<File, List<Item>> getIndex() { return index; } public FileIndexer index() { if (!index.isEmpty()) { return this; } try { doIndex(binaries); for (final String toRemove : filesToRemove) { try { addItem(null, Item.Action.REMOVE, toRemove); } catch (final IOException e) { throw new IllegalArgumentException(e); } } } finally { loaderFactory.release(loader); } return this; } public FileIndexer dump(final PrintStream out) { out.println("Index:"); for (final Map.Entry<File, List<Item>> items : index.entrySet()) { Collections.sort(items.getValue()); out.println(); out.println(" Location: " + items.getKey()); for (final Item i : items.getValue()) { out.println(" - " + i.getPath()); } } return this; } private void doIndex(final File binaries) { if (binaries.isFile()) { if (!ignore.equals(binaries.getName())) { doIndexLeaf(binaries); } } else { final File[] children = binaries.listFiles(); if (children == null) { return; } for (final File file : children) { doIndex(file); } } } private void doIndexLeaf(final File file) { try { final String relative = file.getCanonicalFile().getAbsolutePath().substring(binaryRoot.length()); final String resource = relative.replace(File.separatorChar, '/'); addItem(file, Item.Action.ADD_OR_UPDATE, resource); } catch (final IOException e) { throw new IllegalArgumentException(e); } } private void addItem(final File file, final Item.Action action, final String resource) throws IOException { final File jar = JarLocation.jarFromResource(loader, resource).getCanonicalFile(); List<Item> list = index.get(jar); if (list == null) { list = new ArrayList<Item>(); index.put(jar, list); } list.add(new Item(resource, file, action)); } }