ingo@106: package de.intevation.flys.artifacts.context; ingo@106: ingo@106: import java.io.File; ingo@106: import java.util.ArrayList; ingo@106: import java.util.List; ingo@106: ingo@106: import javax.xml.xpath.XPathConstants; ingo@106: ingo@106: import org.apache.log4j.Logger; ingo@106: ingo@106: import org.w3c.dom.Document; ingo@106: import org.w3c.dom.Element; ingo@106: import org.w3c.dom.NodeList; ingo@106: ingo@106: import de.intevation.artifacts.ArtifactContextFactory; ingo@106: ingo@106: import de.intevation.artifacts.common.utils.XMLUtils; ingo@106: ingo@106: import de.intevation.artifactdatabase.Config; ingo@107: import de.intevation.artifactdatabase.state.State; ingo@107: import de.intevation.artifactdatabase.state.StateEngine; ingo@107: import de.intevation.artifactdatabase.transition.Transition; ingo@107: import de.intevation.artifactdatabase.transition.TransitionEngine; ingo@106: ingo@107: import de.intevation.flys.artifacts.states.StateFactory; ingo@106: import de.intevation.flys.artifacts.transitions.TransitionFactory; ingo@106: ingo@106: ingo@106: /** ingo@106: * The ArtifactContextFactory is used to initialize basic components and put ingo@106: * them into the global context of the application. ingo@106: * ingo@106: * @author Ingo Weinzierl ingo@106: */ ingo@106: public class FLYSContextFactory implements ArtifactContextFactory { ingo@106: ingo@106: /** The logger that is used in this class */ ingo@106: private static Logger logger = Logger.getLogger(FLYSContextFactory.class); ingo@106: ingo@106: /** The XPath to the artifacts configured in the configuration. */ ingo@106: public static final String XPATH_ARTIFACTS = ingo@106: "/artifact-database/artifacts/artifact"; ingo@106: ingo@106: /** The XPath to the name of the artifact. */ ingo@107: public static final String XPATH_ARTIFACT_NAME = "/artifact/@name"; ingo@106: ingo@106: /** The XPath to the xlink ref in an artifact configuration. */ ingo@106: public static final String XPATH_XLINK = "xlink:href"; ingo@106: ingo@106: /** The XPath to the transitions configured in the artifact config. */ ingo@106: public static final String XPATH_TRANSITIONS = ingo@106: "/artifact/states/transition"; ingo@106: ingo@107: /** The XPath to the states configured in the artifact config. */ ingo@107: public static final String XPATH_STATES = ingo@107: "/artifact/states/state"; ingo@107: ingo@106: /** ingo@106: * Creates a new FLYSArtifactContext object and initialize all ingo@106: * components required by the application. ingo@106: * ingo@106: * @param config The artifact server configuration. ingo@106: * @return a FLYSArtifactContext. ingo@106: */ ingo@106: public Object createArtifactContext(Document config) { ingo@106: FLYSContext context = new FLYSContext(config); ingo@106: ingo@106: configureTransitions(config, context); ingo@107: configureStates(config, context); ingo@106: ingo@106: return context; ingo@106: } ingo@106: ingo@106: ingo@106: /** ingo@106: * This method initializes the transition configuration. ingo@106: * ingo@106: * @param config the config document. ingo@106: * @param context the FLYSContext. ingo@106: */ ingo@106: protected void configureTransitions(Document config, FLYSContext context) { ingo@106: TransitionEngine engine = new TransitionEngine(); ingo@106: ingo@106: Document[] artifacts = getArtifactConfigurations(config); ingo@106: logger.info("Found " + artifacts.length + " artifacts in the config."); ingo@106: ingo@106: for (Document doc: artifacts) { ingo@106: List transitions = new ArrayList(); ingo@106: ingo@106: String artName = (String) XMLUtils.xpath( ingo@106: doc, XPATH_ARTIFACT_NAME, XPathConstants.STRING); ingo@106: ingo@106: NodeList transitionList = (NodeList) XMLUtils.xpath( ingo@106: doc, XPATH_TRANSITIONS, XPathConstants.NODESET); ingo@106: ingo@106: if (transitionList == null) { ingo@106: logger.warn("The artifact has no transitions configured."); ingo@107: continue; ingo@106: } ingo@106: ingo@106: int trans = transitionList.getLength(); ingo@106: ingo@106: logger.info( ingo@106: "Artifact '" + artName + "' has " + trans + " transitions."); ingo@106: ingo@106: for (int i = 0; i < trans; i++) { ingo@106: transitions.add(TransitionFactory.createTransition( ingo@106: transitionList.item(i))); ingo@106: } ingo@106: ingo@106: engine.addTransition(artName, transitions); ingo@106: } ingo@106: ingo@106: context.put(FLYSContext.TRANSITION_ENGINE_KEY, engine); ingo@106: } ingo@106: ingo@106: ingo@106: /** ingo@106: * This method returns all artifact documents defined in ingo@106: * config.
NOTE: The artifact configurations need to be ingo@106: * stored in own files referenced by an xlink. ingo@106: * ingo@106: * @param config The global configuration. ingo@106: * ingo@106: * @return an array of Artifact configurations. ingo@106: */ ingo@106: protected Document[] getArtifactConfigurations(Document config) { ingo@106: NodeList artifacts = (NodeList) XMLUtils.xpath( ingo@106: config, XPATH_ARTIFACTS, XPathConstants.NODESET); ingo@106: ingo@106: int count = artifacts.getLength(); ingo@106: ingo@106: Document[] artifactDocs = new Document[count]; ingo@106: ingo@106: for (int i = 0; i < count; i++) { ingo@106: Element tmp = (Element) artifacts.item(i); ingo@106: ingo@106: String xlink = tmp.getAttribute(XPATH_XLINK); ingo@106: xlink = Config.replaceConfigDir(xlink); ingo@106: ingo@106: File artifactFile = new File(xlink); ingo@106: artifactDocs[i] = XMLUtils.parseDocument(artifactFile); ingo@106: } ingo@106: ingo@106: return artifactDocs; ingo@106: } ingo@107: ingo@107: ingo@107: /** ingo@107: * This method initializes the transition configuration. ingo@107: * ingo@107: * @param config the config document. ingo@107: * @param context the FLYSContext. ingo@107: */ ingo@107: protected void configureStates(Document config, FLYSContext context) { ingo@107: StateEngine engine = new StateEngine(); ingo@107: ingo@107: Document[] artifacts = getArtifactConfigurations(config); ingo@107: logger.info("Found " + artifacts.length + " artifacts in the config."); ingo@107: ingo@107: for (Document doc: artifacts) { ingo@107: List states = new ArrayList(); ingo@107: ingo@107: String artName = (String) XMLUtils.xpath( ingo@107: doc, XPATH_ARTIFACT_NAME, XPathConstants.STRING); ingo@107: ingo@107: NodeList stateList = (NodeList) XMLUtils.xpath( ingo@107: doc, XPATH_STATES, XPathConstants.NODESET); ingo@107: ingo@107: if (stateList == null) { ingo@107: logger.warn("The artifact has no states configured."); ingo@107: continue; ingo@107: } ingo@107: ingo@107: int count = stateList.getLength(); ingo@107: ingo@107: logger.info( ingo@107: "Artifact '" + artName + "' has " + count + " states."); ingo@107: ingo@107: for (int i = 0; i < count; i++) { ingo@107: states.add(StateFactory.createState( ingo@107: stateList.item(i))); ingo@107: } ingo@107: ingo@107: engine.addStates(artName, states); ingo@107: } ingo@107: ingo@107: context.put(FLYSContext.STATE_ENGINE_KEY, engine); ingo@107: } ingo@106: } ingo@106: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :