/**
* Copyright (C) 2009 STMicroelectronics
*
* This file is part of "Mind Compiler" is free software: you can redistribute
* it and/or modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Contact: mind@ow2.org
*
* Authors: Matthieu Leclercq
* Contributors:
*/
package org.ow2.mind;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.objectweb.fractal.adl.CompilerError;
import org.objectweb.fractal.adl.error.GenericErrors;
import org.objectweb.fractal.adl.util.ClassLoaderHelper;
import org.objectweb.fractal.adl.util.FractalADLLogManager;
import com.google.inject.Inject;
public class BasicInputResourceLocator implements InputResourceLocator {
protected static Logger logger = FractalADLLogManager
.getLogger("loader.InputResourceLocator");
protected Map<String, GenericResourceLocator> genericResourceLocators;
@Inject
protected void setGenericResourceLocators(
final Set<GenericResourceLocator> locators) {
genericResourceLocators = new HashMap<String, GenericResourceLocator>(
locators.size());
for (final GenericResourceLocator locator : locators) {
for (final String resourceKing : locator.getResourceKind()) {
genericResourceLocators.put(resourceKing, locator);
}
}
}
// ---------------------------------------------------------------------------
// Implementation of the InputResourceLocator interface
// ---------------------------------------------------------------------------
public URL[] getInputResourcesRoot(final Map<Object, Object> context) {
final ClassLoader cl = ClassLoaderHelper.getClassLoader(this, context);
if (cl instanceof URLClassLoader) {
return ((URLClassLoader) cl).getURLs();
}
return null;
}
public URL findResource(final InputResource resource,
final Map<Object, Object> context) {
if (resource.getLocation() != null) return resource.getLocation();
final GenericResourceLocator genericResourceLocator = genericResourceLocators
.get(resource.getKind());
if (genericResourceLocator == null) {
throw new CompilerError(GenericErrors.INTERNAL_ERROR,
"Missing GenericResourceLocator for input resources of kind \""
+ resource.getKind() + "\".");
}
final URL location = genericResourceLocator.findResource(
resource.getName(), context);
if (location != null) resource.setLocation(location);
return location;
}
public boolean isUpToDate(final long timestamp,
final Collection<InputResource> inputs, final Map<Object, Object> context) {
if (ForceRegenContextHelper.getForceRegen(context)) {
if (logger.isLoggable(Level.FINEST))
logger
.log(Level.FINEST, "Forced mode, isUpToDate method return false.");
return false;
}
if (inputs == null) {
// this happens when there is no real file attached to a component.
return false;
}
for (final InputResource dependency : inputs) {
try {
if (getTimestamp(dependency, context) >= timestamp) {
// a dependency is newer than given timestamp.
if (logger.isLoggable(Level.FINEST))
logger.log(Level.FINEST, "Dependency \"" + dependency
+ "\" is more recent (location=\"" + dependency.getLocation()
+ "\"), isUpToDate method return false.");
return false;
}
} catch (final MalformedURLException e) {
if (logger.isLoggable(Level.WARNING))
logger.log(Level.WARNING, "Can't determine file timestamps of "
+ dependency);
// if one dependency is missing consider the file as out of date.
return false;
}
}
if (logger.isLoggable(Level.FINEST))
logger.log(Level.FINEST,
"Dependencies are up-to-dates, isUpToDate method return true.");
return true;
}
public boolean isUpToDate(final File file,
final Collection<InputResource> inputs, final Map<Object, Object> context) {
if (logger.isLoggable(Level.FINEST))
logger.log(Level.FINEST, "Checks if file \"" + file + "\" is up-to-date");
return isUpToDate(file.lastModified(), inputs, context);
}
public boolean isUpToDate(final URL url,
final Collection<InputResource> inputs, final Map<Object, Object> context)
throws MalformedURLException {
if (logger.isLoggable(Level.FINEST))
logger.log(Level.FINEST, "Checks if URL \"" + url + "\" is up-to-date");
return isUpToDate(InputResourcesHelper.getTimestamp(url), inputs, context);
}
// ---------------------------------------------------------------------------
// Utility methods
// ---------------------------------------------------------------------------
protected long getTimestamp(final InputResource resource,
final Map<Object, Object> context) throws MalformedURLException {
long timestamp = resource.getTimestamp();
if (timestamp == -1) {
final URL url = findResource(resource, context);
if (url != null)
timestamp = InputResourcesHelper.getTimestamp(url);
else
timestamp = 0L;
resource.setTimestamp(timestamp);
}
return timestamp;
}
}