ro.isdc.wro.extensions.model.factory.SmartWroModelFactory Maven / Gradle / Ivy
/**
* Copyright@2011 wro4j
*/
package ro.isdc.wro.extensions.model.factory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ro.isdc.wro.WroRuntimeException;
import ro.isdc.wro.manager.factory.standalone.StandaloneContext;
import ro.isdc.wro.model.WroModel;
import ro.isdc.wro.model.factory.AbstractWroModelFactory;
import ro.isdc.wro.model.factory.WroModelFactory;
import ro.isdc.wro.model.factory.XmlModelFactory;
import ro.isdc.wro.model.group.Inject;
import ro.isdc.wro.model.group.processor.Injector;
/**
* When used, this factory will make it possible to migrate easily from xml to groovy (or json) DSL seamlessly.
*
* @author Alex Objelean
* @created 6 Aug 2011
* @since 1.4.0
*/
public class SmartWroModelFactory extends AbstractWroModelFactory {
private static final Logger LOG = LoggerFactory.getLogger(SmartWroModelFactory.class);
/**
* The default location of the wro model file.
*/
private static final String DEFAULT_WRO_FILE = "/src/main/webapp/WEB-INF/wro.xml";
@Inject
private Injector injector;
private List factoryList;
/**
* The exact file where the model is located.
*/
private File wroFile;
/**
* flag indicating if the wroFile should be auto detected.
*/
private boolean autoDetectWroFile = true;
/**
* Use this factory method when you want to use the {@link SmartWroModelFactory} in standalone (maven plugin) context.
* The autoDetect flag is set to true if the wroFile path is the same as the default wro file name.
*/
public static SmartWroModelFactory createFromStandaloneContext(final StandaloneContext context) {
Validate.notNull(context);
final boolean autoDetectWroFile = FilenameUtils.normalize(context.getWroFile().getPath()).contains(
FilenameUtils.normalize(DEFAULT_WRO_FILE));
if (!autoDetectWroFile) {
LOG.debug("autoDetect is " + autoDetectWroFile + " because wroFile: " + context.getWroFile()
+ " is not the same as the default one: " + DEFAULT_WRO_FILE);
}
return new SmartWroModelFactory().setWroFile(context.getWroFile()).setAutoDetectWroFile(autoDetectWroFile);
}
/**
* The file to use for creating model. It is not required to set this field, but if you set, do not set a null object.
*
* @param wroFile the wroFile to set
*/
public SmartWroModelFactory setWroFile(final File wroFile) {
Validate.notNull(wroFile);
this.wroFile = wroFile;
return this;
}
/**
* @return default list of factories to be used by {@link SmartWroModelFactory}.
*/
protected List newWroModelFactoryFactoryList() {
final List factoryList = new ArrayList();
LOG.debug("auto detect wroFile: {}", autoDetectWroFile);
factoryList.add(newXmlModelFactory());
factoryList.add(newGroovyModelFactory());
factoryList.add(newJsonModelFactory());
return factoryList;
}
private XmlModelFactory newXmlModelFactory() {
return new XmlModelFactory() {
@Override
protected InputStream getModelResourceAsStream()
throws IOException {
if (wroFile == null) {
return super.getModelResourceAsStream();
}
return createAutoDetectedStream(getDefaultModelFilename());
}
};
}
private GroovyModelFactory newGroovyModelFactory() {
return new GroovyModelFactory() {
@Override
protected InputStream getModelResourceAsStream()
throws IOException {
if (wroFile == null) {
return super.getModelResourceAsStream();
}
return createAutoDetectedStream(getDefaultModelFilename());
}
};
}
private JsonModelFactory newJsonModelFactory() {
return new JsonModelFactory() {
@Override
protected InputStream getModelResourceAsStream()
throws IOException {
if (wroFile == null) {
return super.getModelResourceAsStream();
}
return createAutoDetectedStream(getDefaultModelFilename());
}
};
}
/**
* Handles the resource model auto detection.
*/
private InputStream createAutoDetectedStream(final String defaultFileName)
throws IOException {
try {
Validate.notNull(wroFile, "Cannot call this method if wroFile is null!");
if (autoDetectWroFile) {
final File file = new File(wroFile.getParentFile(), defaultFileName);
LOG.debug("\tloading autodetected wro file: " + file);
return new FileInputStream(file);
}
LOG.debug("loading wroFile: " + wroFile);
return new FileInputStream(wroFile);
} catch (final FileNotFoundException e) {
// When auto detect is turned on, do not skip trying.. because the auto detection assume that the wro file name
// can be wrong.
if (autoDetectWroFile) {
throw e;
}
throw new WroRuntimeException("The wroFile doesn't exist. Skip trying with other wro model factories", e);
}
}
/**
* {@inheritDoc}
*/
@Override
public WroModel create() {
if (factoryList == null) {
factoryList = newWroModelFactoryFactoryList();
}
if (factoryList != null) {
// Holds the details about model creation which are logged only when no model can be created
final StringBuffer logMessageBuffer = new StringBuffer();
for (final WroModelFactory factory : factoryList) {
try {
//use injector for aggregated modelFactories
injector.inject(factory);
final Class extends WroModelFactory> factoryClass = factory.getClass().asSubclass(WroModelFactory.class);
logMessageBuffer.append(" Using " + getClassName(factoryClass) + " for model creation..\n");
return factory.create();
} catch (final WroRuntimeException e) {
LOG.debug("[FAIL] creating model... will try another factory");
logMessageBuffer.append("[FAIL] Model creation using " + getClassName(factory.getClass())
+ " failed. Trying another ...\n");
logMessageBuffer.append("[FAIL] Exception occured while building the model using: "
+ getClassName(factory.getClass()) + " " + e.getMessage());
// stop trying with other factories if the reason is IOException
if (!autoDetectWroFile && e.getCause() instanceof IOException) {
throw e;
}
}
}
LOG.error(logMessageBuffer.toString());
}
throw new WroRuntimeException("Cannot create model using any of provided factories");
}
/**
* @return string representation of the factory name.
*/
protected String getClassName(final Class extends WroModelFactory> factoryClass) {
final String className = factoryClass.isAnonymousClass()
? factoryClass.getSuperclass().getSimpleName()
: factoryClass.getSimpleName();
return className;
}
/**
* @param factoryList the factoryList to set
*/
public SmartWroModelFactory setFactoryList(final List factoryList) {
Validate.notNull(factoryList);
this.factoryList = factoryList;
return this;
}
/**
* In order to keep backward compatibility for building the model . The idea is if this field is false, then the exact
* file will be used to create the model, otherwise, wro model file is auto-detected based on the parent folder where
* the wroFile is located.
*
* @param autoDetectWroFile the autoDetectWroFile to set
*/
public SmartWroModelFactory setAutoDetectWroFile(final boolean autoDetectWroFile) {
this.autoDetectWroFile = autoDetectWroFile;
return this;
}
/**
* {@inheritDoc}
*/
@Override
protected String getDefaultModelFilename() {
return DEFAULT_WRO_FILE;
}
/**
* {@inheritDoc}
*/
@Override
protected InputStream getModelResourceAsStream()
throws IOException {
throw new IllegalStateException("This method should never be called!");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy