/*
* Copyright 2004-2009 the original author or authors.
*
* 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.compass.core.config.binding;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.compass.core.config.CompassSettings;
import org.compass.core.config.ConfigurationException;
import org.compass.core.config.InputStreamMappingResolver;
import org.compass.core.mapping.ContractMapping;
import org.compass.core.mapping.MappingException;
import org.compass.core.mapping.ResourceMapping;
import org.compass.core.mapping.internal.InternalCompassMapping;
import org.compass.core.metadata.CompassMetaData;
/**
* @author kimchy
*/
public abstract class AbstractInputStreamMappingBinding implements MappingBinding {
protected final Log log = LogFactory.getLog(getClass());
protected InternalCompassMapping mapping;
protected CompassMetaData metaData;
protected CompassSettings settings;
public void setUpBinding(InternalCompassMapping mapping, CompassMetaData metaData, CompassSettings settings) {
this.mapping = mapping;
this.metaData = metaData;
this.settings = settings;
}
public boolean addResourceMapping(ResourceMapping resourceMapping) throws ConfigurationException, MappingException {
mapping.addMapping(resourceMapping);
return true;
}
public boolean addContractMaping(ContractMapping contractMapping) throws ConfigurationException, MappingException {
mapping.addMapping(contractMapping);
return true;
}
public boolean addResource(String path) throws ConfigurationException, MappingException {
return addResource(path, settings.getClassLoader());
}
public boolean addResource(String path, ClassLoader classLoader) throws ConfigurationException, MappingException {
InputStream rsrc = classLoader.getResourceAsStream(path);
return rsrc != null && internalAddInputStream(rsrc, path, true);
}
public boolean addURL(URL url) throws ConfigurationException, MappingException {
try {
return internalAddInputStream(url.openStream(), url.toExternalForm(), true);
} catch (IOException e) {
throw new ConfigurationException("Failed to open url [" + url.toExternalForm() + "]", e);
}
}
public boolean addDirectory(File dir) throws ConfigurationException, MappingException {
boolean addedAtLeastOne = false;
File[] files = dir.listFiles();
for (File file : files) {
if (file.isDirectory()) {
boolean retVal = addDirectory(file);
if (retVal) {
addedAtLeastOne = true;
}
} else {
for (String suffix : getSuffixes()) {
if (file.getName().endsWith(suffix)) {
boolean retVal = addFile(file);
if (retVal) {
addedAtLeastOne = true;
}
}
}
}
}
return addedAtLeastOne;
}
public boolean addJar(File jar) throws ConfigurationException, MappingException {
final JarFile jarFile;
try {
jarFile = new JarFile(jar);
} catch (IOException ioe) {
throw new ConfigurationException("Could not configure datastore from jar [" + jar.getName() + "]", ioe);
}
boolean addedAtLeastOne = false;
Enumeration jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
ZipEntry ze = (ZipEntry) jarEntries.nextElement();
for (String suffix : getSuffixes()) {
if (ze.getName().endsWith(suffix)) {
try {
boolean retVal = internalAddInputStream(jarFile.getInputStream(ze), ze.getName(), true);
if (retVal) {
addedAtLeastOne = true;
}
} catch (ConfigurationException me) {
throw me;
} catch (Exception e) {
throw new ConfigurationException("Could not configure datastore from jar [" + jar.getAbsolutePath() + "]", e);
}
}
}
}
return addedAtLeastOne;
}
public boolean addFile(String filePath) throws ConfigurationException, MappingException {
return addFile(new File(filePath));
}
public boolean addFile(File file) throws ConfigurationException, MappingException {
try {
return internalAddInputStream(new FileInputStream(file), file.getAbsolutePath(), true);
} catch (FileNotFoundException e) {
throw new ConfigurationException("Could not configure mapping from file, file not found ["
+ file.getAbsolutePath() + "]", e);
}
}
public boolean addPackage(String packageName) throws ConfigurationException, MappingException {
// nothing for us to do here
return false;
}
public boolean addClass(Class clazz) throws ConfigurationException, MappingException {
boolean addedAtLeaseOne = false;
for (String suffix : getSuffixes()) {
String fileName = clazz.getName().replace('.', '/') + suffix;
InputStream rsrc = clazz.getClassLoader().getResourceAsStream(fileName);
if (rsrc == null) {
continue;
}
try {
addedAtLeaseOne |= internalAddInputStream(rsrc, fileName, true);
} catch (ConfigurationException me) {
throw new ConfigurationException("Error reading resource [" + fileName + "]", me);
}
}
return addedAtLeaseOne;
}
public boolean addMappingResolver(InputStreamMappingResolver mappingResolver) throws ConfigurationException, MappingException {
return internalAddInputStream(mappingResolver.getMappingAsInputStream(), mappingResolver.getName(), true);
}
public boolean addInputStream(InputStream is, String resourceName) throws ConfigurationException, MappingException {
return internalAddInputStream(is, resourceName, false);
}
private boolean internalAddInputStream(InputStream is, String resourceName, boolean closeStream) throws ConfigurationException, MappingException {
try {
boolean matchedOnSuffix = false;
for (String suffix : getSuffixes()) {
if (resourceName.endsWith(suffix)) {
matchedOnSuffix = true;
break;
}
}
if (!matchedOnSuffix) {
if (log.isTraceEnabled()) {
log.trace("Resource name [" + resourceName + "] does not end with suffix [" + Arrays.toString(getSuffixes()) + "], ignoring");
}
return false;
}
return doAddInputStream(is, resourceName);
} finally {
if (closeStream) {
try {
is.close();
} catch (IOException ioe) {
// ignore
}
}
}
}
protected abstract boolean doAddInputStream(InputStream is, String resourceName)
throws ConfigurationException, MappingException;
}