ingo@2693: package de.intevation.flys.artifacts; ingo@2693: ingo@2693: import de.intevation.artifactdatabase.ProtocolUtils; ingo@2693: ingo@2693: import de.intevation.artifactdatabase.state.Output; ingo@2693: import de.intevation.artifactdatabase.state.State; ingo@2693: import de.intevation.artifactdatabase.state.StateEngine; ingo@2693: ingo@2693: import de.intevation.artifactdatabase.transition.TransitionEngine; ingo@2693: ingo@2693: import de.intevation.artifacts.CallContext; ingo@2693: import de.intevation.artifacts.Message; ingo@2693: ingo@2693: import de.intevation.artifacts.common.ArtifactNamespaceContext; ingo@2693: ingo@2693: import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator; ingo@2693: ingo@2693: import de.intevation.artifacts.common.utils.XMLUtils; ingo@2693: ingo@2693: import de.intevation.flys.artifacts.context.FLYSContext; ingo@2693: ingo@2693: import de.intevation.flys.artifacts.model.CalculationMessage; ingo@2693: import de.intevation.flys.artifacts.model.FacetTypes; ingo@2693: ingo@2693: import de.intevation.flys.artifacts.states.DefaultState; ingo@2713: import de.intevation.flys.artifacts.states.SoundingsSelect; ingo@2693: ingo@2693: import de.intevation.flys.utils.FLYSUtils; ingo@2693: ingo@2713: import gnu.trove.TIntArrayList; ingo@2713: ingo@2693: import java.util.LinkedList; ingo@2693: import java.util.List; ingo@2693: ingo@2693: import org.apache.log4j.Logger; ingo@2693: ingo@2693: import org.w3c.dom.Document; ingo@2693: import org.w3c.dom.Element; ingo@2693: import org.w3c.dom.Node; ingo@2693: ingo@2693: /** ingo@2693: * The default MINFO artifact. ingo@2693: * ingo@2693: * @author Ingo Weinzierl ingo@2693: */ ingo@2693: public class MINFOArtifact ingo@2693: extends FLYSArtifact ingo@2693: implements FacetTypes { ingo@2693: ingo@2693: /** The logger for this class. */ ingo@2693: private static Logger logger = Logger.getLogger(MINFOArtifact.class); ingo@2693: ingo@2693: /** The name of the artifact. */ ingo@2693: public static final String ARTIFACT_NAME = "minfo"; ingo@2693: ingo@2693: /** XPath */ ingo@2693: public static final String XPATH_STATIC_UI ="/art:result/art:ui/art:static"; ingo@2693: ingo@2693: ingo@2693: /** ingo@2693: * The default constructor. ingo@2693: */ ingo@2693: public MINFOArtifact() { ingo@2693: } ingo@2693: ingo@2693: ingo@2693: /** ingo@2693: * This method returns a description of this artifact. ingo@2693: * ingo@2693: * @param data Some data. ingo@2693: * @param context The CallContext. ingo@2693: * ingo@2693: * @return the description of this artifact. ingo@2693: */ ingo@2693: public Document describe(Document data, CallContext context) { ingo@2693: logger.debug("Describe: the current state is: " + getCurrentStateId()); ingo@2693: ingo@2693: FLYSContext flysContext = FLYSUtils.getFlysContext(context); ingo@2693: StateEngine stateEngine = (StateEngine) flysContext.get( ingo@2693: FLYSContext.STATE_ENGINE_KEY); ingo@2693: ingo@2693: TransitionEngine transitionEngine = (TransitionEngine) flysContext.get( ingo@2693: FLYSContext.TRANSITION_ENGINE_KEY); ingo@2693: ingo@2693: List reachable = transitionEngine.getReachableStates( ingo@2693: this, getCurrentState(context), stateEngine); ingo@2693: ingo@2693: Document description = XMLUtils.newDocument(); ingo@2693: XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( ingo@2693: description, ingo@2693: ArtifactNamespaceContext.NAMESPACE_URI, ingo@2693: ArtifactNamespaceContext.NAMESPACE_PREFIX); ingo@2693: ingo@2693: Element root = ProtocolUtils.createRootNode(creator); ingo@2693: description.appendChild(root); ingo@2693: ingo@2693: State current = getCurrentState(context); ingo@2693: ingo@2693: ProtocolUtils.appendDescribeHeader(creator, root, identifier(), hash()); ingo@2693: ProtocolUtils.appendState(creator, root, current); ingo@2693: ProtocolUtils.appendReachableStates(creator, root, reachable); ingo@2693: ingo@2693: appendBackgroundActivity(creator, root, context); ingo@2693: ingo@2693: Element name = ProtocolUtils.createArtNode( ingo@2693: creator, "name", ingo@2693: new String[] { "value" }, ingo@2693: new String[] { getName() }); ingo@2693: ingo@2693: Element ui = ProtocolUtils.createArtNode( ingo@2693: creator, "ui", null, null); ingo@2693: ingo@2693: Element staticUI = ProtocolUtils.createArtNode( ingo@2693: creator, "static", null, null); ingo@2693: ingo@2693: Element outs = ProtocolUtils.createArtNode( ingo@2693: creator, "outputmodes", null, null); ingo@2693: appendOutputModes(description, outs, context, identifier()); ingo@2693: ingo@2693: appendStaticUI(description, staticUI, context, identifier()); ingo@2693: ingo@2693: Element dynamic = current.describe( ingo@2693: this, ingo@2693: description, ingo@2693: root, ingo@2693: context, ingo@2693: identifier()); ingo@2693: ingo@2693: if (dynamic != null) { ingo@2693: ui.appendChild(dynamic); ingo@2693: } ingo@2693: ingo@2693: ui.appendChild(staticUI); ingo@2693: ingo@2693: root.appendChild(name); ingo@2693: root.appendChild(ui); ingo@2693: root.appendChild(outs); ingo@2693: ingo@2693: return description; ingo@2693: } ingo@2693: ingo@2693: ingo@2693: /** ingo@2693: * Returns the name of the concrete artifact. ingo@2693: * ingo@2693: * @return the name of the concrete artifact. ingo@2693: */ ingo@2693: public String getName() { ingo@2693: return ARTIFACT_NAME; ingo@2693: } ingo@2693: ingo@2693: ingo@2693: protected static void appendBackgroundActivity( ingo@2693: ElementCreator cr, ingo@2693: Element root, ingo@2693: CallContext context ingo@2693: ) { ingo@2693: Element inBackground = cr.create("background-processing"); ingo@2693: root.appendChild(inBackground); ingo@2693: ingo@2693: cr.addAttr( ingo@2693: inBackground, ingo@2693: "value", ingo@2693: String.valueOf(context.isInBackground()), ingo@2693: true); ingo@2693: ingo@2693: LinkedList messages = context.getBackgroundMessages(); ingo@2693: ingo@2693: if (messages == null) { ingo@2693: return; ingo@2693: } ingo@2693: ingo@2693: CalculationMessage message = (CalculationMessage) messages.getLast(); ingo@2693: cr.addAttr( ingo@2693: inBackground, ingo@2693: "steps", ingo@2693: String.valueOf(message.getSteps()), ingo@2693: true); ingo@2693: ingo@2693: cr.addAttr( ingo@2693: inBackground, ingo@2693: "currentStep", ingo@2693: String.valueOf(message.getCurrentStep()), ingo@2693: true); ingo@2693: ingo@2693: inBackground.setTextContent(message.getMessage()); ingo@2693: } ingo@2693: ingo@2693: ingo@2693: /** ingo@2693: * Append output mode nodes to a document. ingo@2693: */ ingo@2693: protected void appendOutputModes( ingo@2693: Document doc, ingo@2693: Element outs, ingo@2693: CallContext context, ingo@2693: String uuid) ingo@2693: { ingo@2693: List generated = getOutputs(context); ingo@2693: logger.debug("This Artifact has " + generated.size() + " Outputs."); ingo@2693: ingo@2693: ProtocolUtils.appendOutputModes(doc, outs, generated); ingo@2693: } ingo@2693: ingo@2693: ingo@2693: /** ingo@2693: * This method appends the static data - that has already been inserted by ingo@2693: * the user - to the static node of the DESCRIBE document. ingo@2693: * ingo@2693: * @param doc The document. ingo@2693: * @param ui The root node. ingo@2693: * @param context The CallContext. ingo@2693: * @param uuid The identifier of the artifact. ingo@2693: */ ingo@2693: protected void appendStaticUI( ingo@2693: Document doc, ingo@2693: Node ui, ingo@2693: CallContext context, ingo@2693: String uuid) ingo@2693: { ingo@2693: List stateIds = getPreviousStateIds(); ingo@2693: ingo@2693: FLYSContext flysContext = FLYSUtils.getFlysContext(context); ingo@2693: StateEngine engine = (StateEngine) flysContext.get( ingo@2693: FLYSContext.STATE_ENGINE_KEY); ingo@2693: ingo@2693: for (String stateId: stateIds) { ingo@2693: logger.debug("Append static data for state: " + stateId); ingo@2693: DefaultState state = (DefaultState) engine.getState(stateId); ingo@2693: ingo@2693: ui.appendChild(state.describeStatic(this, doc, ui, context, uuid)); ingo@2693: } ingo@2693: } ingo@2693: ingo@2693: ingo@2693: /** ingo@2693: * Determines Facets initial disposition regarding activity (think of ingo@2693: * selection in Client ThemeList GUI). This will be checked one time ingo@2693: * when the facet enters a collections describe document. ingo@2693: * ingo@2693: * @param facetName name of the facet. ingo@2693: * @param index index of the facet. ingo@2693: * @return 0 if not active ingo@2693: */ ingo@2693: @Override ingo@2693: public int getInitialFacetActivity(String outputName, String facetName, int index) { ingo@2693: logger.warn("MINFOArtifact.getInitialFacetActivity: not implemented!"); ingo@2693: return 1; ingo@2693: } ingo@2702: ingo@2702: ingo@2702: public int[] getMainChannels() { ingo@2702: String data = getDataAsString("main.channel"); ingo@2702: ingo@2702: if (data == null) { ingo@2702: logger.warn("No 'main.channel' parameter specified!"); ingo@2702: return null; ingo@2702: } ingo@2702: ingo@2702: return FLYSUtils.intArrayFromString(data); ingo@2702: } ingo@2702: ingo@2702: ingo@2702: public int[] getTotalChannels() { ingo@2702: String data = getDataAsString("total.channel"); ingo@2702: ingo@2702: if (data == null) { ingo@2702: logger.warn("No 'total.channel' parameter specified!"); ingo@2702: return null; ingo@2702: } ingo@2702: ingo@2702: return FLYSUtils.intArrayFromString(data); ingo@2702: } ingo@2713: ingo@2713: ingo@2713: public int[] getBedHeightSingleIDs() { ingo@2713: String data = getDataAsString("soundings"); ingo@2713: ingo@2713: if (data == null) { ingo@2713: logger.warn("No 'soundings' parameter specified!"); ingo@2713: return null; ingo@2713: } ingo@2713: ingo@2713: String[] parts = data.split(";"); ingo@2713: ingo@2713: TIntArrayList ids = new TIntArrayList(); ingo@2713: ingo@2713: for (String part: parts) { ingo@2713: if (part.indexOf(SoundingsSelect.PREFIX_SINGLE) >= 0) { ingo@2713: String tmp = part.replace(SoundingsSelect.PREFIX_SINGLE, ""); ingo@2713: ingo@2713: try { ingo@2713: ids.add(Integer.parseInt(tmp)); ingo@2713: } ingo@2713: catch (NumberFormatException nfe) { ingo@2713: logger.warn("Cannot parse int from string: '" + tmp + "'"); ingo@2713: } ingo@2713: } ingo@2713: } ingo@2713: ingo@2713: return ids.toNativeArray(); ingo@2713: } ingo@2713: ingo@2713: ingo@2713: public int[] getBedHeightEpochIDs() { ingo@2713: String data = getDataAsString("soundings"); ingo@2713: ingo@2713: if (data == null) { ingo@2713: logger.warn("No 'soundings' parameter specified!"); ingo@2713: return null; ingo@2713: } ingo@2713: ingo@2713: String[] parts = data.split(";"); ingo@2713: ingo@2713: TIntArrayList ids = new TIntArrayList(); ingo@2713: ingo@2713: for (String part: parts) { ingo@2713: if (part.indexOf(SoundingsSelect.PREFIX_EPOCH) >= 0) { ingo@2713: String tmp = part.replace(SoundingsSelect.PREFIX_EPOCH, ""); ingo@2713: ingo@2713: try { ingo@2713: ids.add(Integer.parseInt(tmp)); ingo@2713: } ingo@2713: catch (NumberFormatException nfe) { ingo@2713: logger.warn("Cannot parse int from string: '" + tmp + "'"); ingo@2713: } ingo@2713: } ingo@2713: } ingo@2713: ingo@2713: return ids.toNativeArray(); ingo@2713: } ingo@2693: } ingo@2693: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :