| /* |
| * 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.felix.ipojo.manipulator.store; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.util.Collections; |
| import java.util.jar.Manifest; |
| |
| import org.apache.felix.ipojo.manipulator.ResourceStore; |
| import org.apache.felix.ipojo.manipulator.ResourceVisitor; |
| import org.apache.felix.ipojo.manipulator.store.mapper.FileSystemResourceMapper; |
| import org.apache.felix.ipojo.manipulator.store.mapper.IdentityResourceMapper; |
| import org.apache.felix.ipojo.manipulator.util.Metadatas; |
| import org.apache.felix.ipojo.manipulator.util.Streams; |
| import org.apache.felix.ipojo.metadata.Element; |
| |
| /** |
| * A {@link DirectoryResourceStore} knows how to read and write |
| * resources from (to respectively) a File directory. |
| * |
| * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a> |
| */ |
| public class DirectoryResourceStore implements ResourceStore { |
| |
| /** |
| * Source directory where bytecode is read. |
| */ |
| private File m_source; |
| |
| /** |
| * Target directory. |
| */ |
| private File m_target; |
| |
| /** |
| * The builder of the updated manifest. |
| */ |
| private ManifestBuilder m_manifestBuilder; |
| |
| /** |
| * Original manifest to be updated. |
| */ |
| private Manifest m_manifest; |
| |
| /** |
| * Location of the manifest file to update. |
| */ |
| private File m_manifest_file; |
| |
| /** |
| * Resource Mapper. |
| */ |
| private ResourceMapper m_mapper = new FileSystemResourceMapper(new IdentityResourceMapper()); |
| |
| public DirectoryResourceStore(File source) { |
| this(source, source); |
| } |
| |
| public DirectoryResourceStore(File source, File target) { |
| m_source = source; |
| m_target = target; |
| } |
| |
| public void setResourceMapper(ResourceMapper mapper) { |
| m_mapper = new FileSystemResourceMapper(mapper); |
| } |
| |
| public void setManifestBuilder(ManifestBuilder manifestBuilder) { |
| m_manifestBuilder = manifestBuilder; |
| } |
| |
| public void setManifest(Manifest manifest) { |
| m_manifest = manifest; |
| } |
| |
| public void setManifestFile(File manifestFile){ |
| m_manifest_file = manifestFile; |
| } |
| |
| public byte[] read(String path) throws IOException { |
| File resource = new File(m_source, m_mapper.internalize(path)); |
| if (!resource.isFile()) { |
| throw new IOException("File '" + resource + "' is not found (for class " + path + ")."); |
| } |
| return Streams.readBytes(new FileInputStream(resource)); |
| } |
| |
| public void accept(ResourceVisitor visitor) { |
| traverseDirectory(m_source, visitor); |
| } |
| |
| private void traverseDirectory(File directory, ResourceVisitor visitor) { |
| for (File child : directory.listFiles()) { |
| if (child.isDirectory()) { |
| traverseDirectory(child, visitor); |
| } else { |
| visitor.visit(getRelativeName(child)); |
| } |
| } |
| } |
| |
| private String getRelativeName(File file) { |
| String relative = file.getPath().substring(m_source.getPath().length()); |
| return m_mapper.externalize(relative); |
| } |
| |
| public void open() throws IOException { |
| |
| // Update the manifest |
| Manifest updated = m_manifestBuilder.build(m_manifest); |
| |
| // Write it to disk |
| OutputStream os = new FileOutputStream(m_manifest_file); |
| try { |
| updated.write(os); |
| } finally { |
| Streams.close(os); |
| } |
| |
| } |
| |
| public void writeMetadata(Element metadata) { |
| m_manifestBuilder.addMetada(Collections.singletonList(metadata)); |
| m_manifestBuilder.addReferredPackage(Metadatas.findReferredPackages(metadata)); |
| } |
| |
| public void write(String resourcePath, byte[] bytecode) throws IOException { |
| |
| // Internalize the name |
| File resource = new File(m_target, m_mapper.internalize(resourcePath)); |
| |
| // Create intermediate directories if needed |
| if (!resource.getParentFile().exists()) { |
| resource.getParentFile().mkdirs(); |
| } |
| |
| FileOutputStream fos = new FileOutputStream(resource); |
| try { |
| fos.write(bytecode); |
| fos.flush(); |
| } finally { |
| Streams.close(fos); |
| } |
| } |
| |
| public void close() throws IOException { |
| // Nothing to do |
| } |
| } |