ingo@100: /*
ingo@100: * Copyright (c) 2010 by Intevation GmbH
ingo@100: *
ingo@100: * This program is free software under the LGPL (>=v2.1)
ingo@100: * Read the file LGPL.txt coming with the software for details
ingo@100: * or visit http://www.gnu.org/licenses/ if it does not exist.
ingo@100: */
ingo@100:
teichmann@475: package org.dive4elements.artifactdatabase;
sascha@207:
rrenkert@513: import java.util.ArrayList;
rrenkert@513: import java.util.HashMap;
rrenkert@513: import java.util.List;
rrenkert@513: import java.util.Map;
rrenkert@513:
rrenkert@513: import javax.xml.xpath.XPathConstants;
rrenkert@513:
teichmann@475: import org.dive4elements.artifacts.common.utils.Config;
rrenkert@513: import org.dive4elements.artifacts.common.utils.XMLUtils;
teichmann@475:
teichmann@475: import org.dive4elements.artifacts.Artifact;
teichmann@475: import org.dive4elements.artifacts.ArtifactFactory;
teichmann@475: import org.dive4elements.artifacts.ArtifactSerializer;
teichmann@475: import org.dive4elements.artifacts.CallMeta;
teichmann@475: import org.dive4elements.artifacts.GlobalContext;
sascha@10:
sascha@93: import org.apache.log4j.Logger;
sascha@93:
sascha@93: import org.w3c.dom.Document;
teichmann@517: import org.w3c.dom.Element;
sascha@93: import org.w3c.dom.Node;
rrenkert@513: import org.w3c.dom.NodeList;
sascha@93:
sascha@17: /**
sascha@90: * Trivial implementation of the ArtifactFactory interface.
sascha@90: * Time to live (ttl), name and description are configured
sascha@90: * via the Node given to #setup(Document, Node) with attributes
sascha@90: * of same name. The class name of the artifacts to be build by this
sascha@90: * factory is configures with the attribute 'artifact'.
sascha@90: *
sascha@77: * @author Sascha L. Teichmann
sascha@17: */
sascha@10: public class DefaultArtifactFactory
sascha@10: implements ArtifactFactory
sascha@10: {
sascha@17: private static Logger logger =
sascha@17: Logger.getLogger(DefaultArtifactFactory.class);
sascha@17:
sascha@90: /**
sascha@90: * XPath to access the TTL of this artifact.
sascha@90: */
sascha@10: public static final String XPATH_TTL = "@ttl";
sascha@90: /**
sascha@90: * XPath to access the name of this factory.
sascha@90: */
sascha@10: public static final String XPATH_NAME = "@name";
sascha@90: /**
sascha@90: * XPath to access the description of this artifact factory.
sascha@90: */
sascha@10: public static final String XPATH_DESCRIPTION = "@description";
sascha@90: /**
sascha@90: * XPath to access the class name of the artifacts to be build
sascha@90: * by this factory.
sascha@90: */
sascha@10: public static final String XPATH_ARTIFACT = "@artifact";
rrenkert@513: /**
rrenkert@513: * XPath to access the static facets configured for artifacts
rrenkert@513: */
rrenkert@513: public static final String XPATH_ARTIFACT_CONFIG =
rrenkert@513: "/artifact-database/artifacts/artifact[@name=$name]/load-facets/facet";
rrenkert@513:
rrenkert@513: /**
rrenkert@513: * XPath to access the static facets configured for artifacts
rrenkert@513: */
rrenkert@513: public static final String XPATH_ARTIFACT_NAME =
rrenkert@513: "/artifact-database/artifacts/artifact/@name";
sascha@10:
sascha@90: /**
sascha@90: * Default description of this factory if none is given by the
sascha@90: * configuration.
sascha@90: */
sascha@10: public static final String DEFAULT_DESCRIPTION =
sascha@10: "No description available";
sascha@10:
sascha@90: /**
sascha@90: * Class to load if no artifact class is given in the configuration.
sascha@90: */
sascha@10: public static final String DEFAULT_ARTIFACT =
teichmann@475: "org.dive4elements.artifactdatabase.DefaultArtifact";
sascha@10:
sascha@90: /**
sascha@90: * The Time to live of the artifacts build by this factory.
sascha@90: */
sascha@10: protected Long ttl;
sascha@10:
sascha@90: /**
sascha@90: * The name of this factory.
sascha@90: */
sascha@10: protected String name;
sascha@10:
sascha@90: /**
sascha@90: * The description of this factory.
sascha@90: */
sascha@10: protected String description;
sascha@10:
sascha@90: /**
sascha@90: * The class of the artifacts to be build by this factory.
sascha@90: */
sascha@10: protected Class artifactClass;
sascha@10:
sascha@90: /**
rrenkert@513: * The name of the artifacts to be build by this factory.
rrenkert@513: */
rrenkert@513: protected String artifactName;
rrenkert@513:
rrenkert@513: /**
rrenkert@513: * The list of facets the generated artifact creates on instantiation.
rrenkert@513: */
rrenkert@513: protected List facetClasses;
rrenkert@513:
rrenkert@513: /**
sascha@90: * Default constructor.
sascha@90: */
sascha@10: public DefaultArtifactFactory() {
rrenkert@513: facetClasses = new ArrayList();
sascha@10: }
sascha@10:
sascha@10: public String getName() {
sascha@10: return name;
sascha@10: }
sascha@10:
sascha@10: public String getDescription() {
sascha@10: return description;
sascha@10: }
sascha@10:
sascha@90: public Artifact createArtifact(
ingo@293: String identifier,
ingo@293: GlobalContext context,
ingo@297: CallMeta callMeta,
ingo@293: Document data
sascha@90: ) {
sascha@10: try {
sascha@10: Artifact artifact =
sascha@10: (Artifact)artifactClass.newInstance();
teichmann@517: String oldName = artifact.getName();
sascha@10:
teichmann@517: if (oldName == null || oldName.length() == 0) {
rrenkert@533: artifact.setName(name);
rrenkert@513: }
rrenkert@513: artifact.setup(
rrenkert@513: identifier,
rrenkert@513: this,
rrenkert@513: context,
rrenkert@513: callMeta,
rrenkert@513: data,
rrenkert@513: facetClasses);
sascha@10:
sascha@10: return artifact;
sascha@10: }
sascha@10: catch (InstantiationException ie) {
sascha@17: logger.error(ie.getLocalizedMessage(), ie);
sascha@10: }
sascha@10: catch (IllegalAccessException iae) {
sascha@17: logger.error(iae.getLocalizedMessage(), iae);
sascha@10: }
sascha@10: catch (ClassCastException cce) {
sascha@17: logger.error(cce.getLocalizedMessage(), cce);
sascha@10: }
sascha@10:
sascha@10: return null;
sascha@10: }
sascha@10:
sascha@10: public void setup(Document document, Node factoryNode) {
teichmann@517: boolean debug = logger.isDebugEnabled();
teichmann@517:
sascha@10: String ttlString = Config.getStringXPath(factoryNode, XPATH_TTL);
sascha@10: if (ttlString != null) {
sascha@10: try {
sascha@10: ttl = Long.valueOf(ttlString);
sascha@10: }
sascha@10: catch (NumberFormatException nfe) {
sascha@17: logger.warn("'" + ttlString + "' is not an integer.");
sascha@10: }
sascha@10: }
sascha@10:
sascha@10: description = Config.getStringXPath(
sascha@10: factoryNode, XPATH_DESCRIPTION, DEFAULT_DESCRIPTION);
sascha@10:
sascha@10: name = Config.getStringXPath(
sascha@10: factoryNode, XPATH_NAME, toString());
teichmann@517:
teichmann@517: if (debug) {
teichmann@517: logger.debug("setting up " + name);
teichmann@517: }
sascha@10:
sascha@10: String artifact = Config.getStringXPath(
sascha@10: factoryNode, XPATH_ARTIFACT, DEFAULT_ARTIFACT);
sascha@10:
rrenkert@513: artifactName = Config.getStringXPath(
rrenkert@513: document, XPATH_ARTIFACT_NAME, "default");
teichmann@517:
teichmann@517: if (debug) {
teichmann@517: logger.debug("artifact name: " + artifactName);
teichmann@517: }
rrenkert@513: Map variables = new HashMap();
rrenkert@513: variables.put("name", name);
rrenkert@513: NodeList facets = (NodeList) XMLUtils.xpath(
rrenkert@513: document,
rrenkert@513: XPATH_ARTIFACT_CONFIG,
rrenkert@513: XPathConstants.NODESET,
rrenkert@513: null,
rrenkert@513: variables);
rrenkert@513:
teichmann@517: for (int i = 0, F = facets.getLength(); i < F; i++) {
teichmann@517: Element element = (Element)facets.item(i);
teichmann@517: String className = element.getAttribute("class");
teichmann@517:
teichmann@517: if (debug) {
teichmann@517: logger.debug("load facet class: " + className);
teichmann@517: }
teichmann@517:
rrenkert@513: try {
rrenkert@513: facetClasses.add(Class.forName(className));
rrenkert@513: }
rrenkert@513: catch (ClassNotFoundException cnfe) {
rrenkert@513: logger.error(cnfe.getLocalizedMessage(), cnfe);
rrenkert@513: }
rrenkert@513: }
teichmann@517:
sascha@10: try {
sascha@10: artifactClass = Class.forName(artifact);
sascha@10: }
sascha@10: catch (ClassNotFoundException cnfe) {
sascha@17: logger.error(cnfe.getLocalizedMessage(), cnfe);
sascha@10: }
sascha@10:
sascha@10: if (artifactClass == null) {
sascha@10: artifactClass = DefaultArtifact.class;
sascha@10: }
sascha@10: }
sascha@10:
sascha@10: public Long timeToLiveUntouched(Artifact artifact, Object context) {
sascha@10: return ttl;
sascha@10: }
sascha@41:
sascha@41: public ArtifactSerializer getSerializer() {
sascha@41: return DefaultArtifactSerializer.INSTANCE;
sascha@41: }
sascha@10: }
sascha@91: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :