ingo@147: package de.intevation.flys.collections;
ingo@147:
ingo@300: import java.io.IOException;
ingo@300: import java.io.OutputStream;
ingo@300: import java.util.ArrayList;
ingo@147: import java.util.Date;
ingo@638: import java.util.HashMap;
ingo@300: import java.util.List;
ingo@300: import java.util.Map;
ingo@370: import java.util.Vector;
ingo@147:
ingo@147: import javax.xml.xpath.XPathConstants;
ingo@147:
ingo@147: import org.apache.log4j.Logger;
ingo@147:
ingo@147: import org.w3c.dom.Document;
ingo@147: import org.w3c.dom.Element;
ingo@147: import org.w3c.dom.Node;
ingo@293: import org.w3c.dom.NodeList;
ingo@147:
ingo@300: import de.intevation.artifacts.Artifact;
ingo@293: import de.intevation.artifacts.ArtifactDatabase;
ingo@293: import de.intevation.artifacts.ArtifactDatabaseException;
ingo@147: import de.intevation.artifacts.ArtifactNamespaceContext;
ingo@147: import de.intevation.artifacts.CallContext;
ingo@293: import de.intevation.artifacts.CallMeta;
ingo@147:
ingo@350: import de.intevation.artifacts.common.utils.ClientProtocolUtils;
ingo@147: import de.intevation.artifacts.common.utils.XMLUtils;
ingo@147:
ingo@300: import de.intevation.artifactdatabase.Backend;
ingo@300: import de.intevation.artifactdatabase.Backend.PersistentArtifact;
ingo@147: import de.intevation.artifactdatabase.DefaultArtifactCollection;
ingo@147:
ingo@300: import de.intevation.flys.artifacts.context.FLYSContext;
ingo@347: import de.intevation.flys.artifacts.model.ManagedFacet;
ingo@300: import de.intevation.flys.exports.OutGenerator;
ingo@350: import de.intevation.flys.themes.Theme;
ingo@350: import de.intevation.flys.themes.ThemeFactory;
ingo@300:
ingo@147:
ingo@147: /**
ingo@147: * @author Ingo Weinzierl
ingo@147: */
ingo@147: public class FLYSArtifactCollection extends DefaultArtifactCollection {
ingo@147:
ingo@147: /** The logger used in this class.*/
ingo@147: private static Logger log = Logger.getLogger(FLYSArtifactCollection.class);
ingo@147:
ingo@147:
ingo@147: /** Constant XPath that points to the outputmodes of an artifact.*/
ingo@147: public static final String XPATH_ARTIFACT_OUTPUTMODES =
ingo@147: "/art:result/art:outputmodes";
ingo@147:
ingo@293: public static final String XPATH_COLLECTION_ITEMS =
ingo@293: "/art:result/art:artifact-collection/art:collection-item";
ingo@293:
ingo@300: public static final String XPATH_OUT_NAME = "/art:action/@art:name";
ingo@300:
ingo@300: public static final String XPATH_OUT_TYPE = "/art:action/@art:type";
ingo@300:
ingo@300:
ingo@147:
ingo@147: @Override
ingo@147: public Document describe(CallContext context) {
ingo@147: log.debug("FLYSArtifactCollection.describe: " + identifier);
ingo@147:
ingo@147: Document doc = XMLUtils.newDocument();
ingo@147:
ingo@147: XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
ingo@147: doc,
ingo@147: ArtifactNamespaceContext.NAMESPACE_URI,
ingo@147: ArtifactNamespaceContext.NAMESPACE_PREFIX);
ingo@147:
ingo@147: Date creationTime = getCreationTime();
ingo@147: String creation = creationTime != null
ingo@147: ? Long.toString(creationTime.getTime())
ingo@147: : "";
ingo@147:
ingo@147: Element collection = ec.create("artifact-collection");
ingo@147: Element artifacts = ec.create("artifacts");
ingo@147:
ingo@147: ec.addAttr(collection, "name", getName(), true);
ingo@147: ec.addAttr(collection, "uuid", identifier(), true);
ingo@147: ec.addAttr(collection, "creation", creation, true);
ingo@147:
ingo@147: collection.appendChild(artifacts);
ingo@147: doc.appendChild(collection);
ingo@147:
ingo@346: ArtifactDatabase db = context.getDatabase();
ingo@293:
ingo@300: try {
ingo@300: String[] artifactUUIDs = getArtifactUUIDs(context);
ingo@293:
ingo@346: Document oldAttrs = getAttribute();
ingo@638:
ingo@638: Document attrs = buildAttributes(
ingo@346: db, context,
ingo@346: oldAttrs,
ingo@346: artifactUUIDs);
ingo@346:
ingo@638: collection.appendChild(doc.importNode(attrs.getFirstChild(), true));
ingo@638:
ingo@638: // save the merged document into database
ingo@638: db.setCollectionAttribute(identifier(), context.getMeta(), attrs);
ingo@346:
ingo@300: for (String uuid: artifactUUIDs) {
ingo@293: try {
ingo@293: artifacts.appendChild(
ingo@293: buildArtifactNode(db, uuid, context, ec));
ingo@293: }
ingo@293: catch (ArtifactDatabaseException dbe) {
ingo@293: log.warn(dbe, dbe);
ingo@293: }
ingo@293: }
ingo@293: }
ingo@293: catch (ArtifactDatabaseException ade) {
ingo@293: log.error(ade, ade);
ingo@147: }
ingo@147:
ingo@147: return doc;
ingo@147: }
ingo@147:
ingo@147:
ingo@300: @Override
ingo@300: public void out(Document format, OutputStream out, CallContext context)
ingo@300: throws IOException
ingo@300: {
ingo@300: log.info("FLYSArtifactCollection.out");
ingo@300:
ingo@300: String name = XMLUtils.xpathString(
ingo@300: format, XPATH_OUT_NAME, ArtifactNamespaceContext.INSTANCE);
ingo@300:
ingo@300: String type = XMLUtils.xpathString(
ingo@300: format, XPATH_OUT_TYPE, ArtifactNamespaceContext.INSTANCE);
ingo@300:
ingo@388: log.debug("Output name = " + name);
ingo@388: log.debug("Output type = " + type);
ingo@388:
ingo@300: OutGenerator generator = getOutGenerator(context, name, type);
ingo@300: if (generator == null) {
ingo@390: log.error("There is no generator specified for output: " + name);
ingo@300: // TODO throw an exception.
ingo@300:
ingo@300: return;
ingo@300: }
ingo@300:
ingo@300: generator.init(format, out, context);
ingo@300:
ingo@412: // TODO Determine the correct master artifact here!
ingo@412:
ingo@300: try {
ingo@388: doOut(generator, name, type, getAttribute(context, name), context);
ingo@347: }
ingo@347: catch (ArtifactDatabaseException adbe) {
ingo@347: log.error(adbe, adbe);
ingo@347: }
ingo@347: }
ingo@300:
ingo@347:
ingo@347: /**
ingo@347: * This method creates the concrete output.
ingo@347: *
ingo@347: * @param generator The OutGenerator that creates the output.
ingo@350: * @param outputName The name of the requested output.
ingo@347: * @param attributes The collection's attributes for this concrete output
ingo@347: * type.
ingo@347: * @param context The context object.
ingo@347: */
ingo@347: protected void doOut(
ingo@347: OutGenerator generator,
ingo@350: String outName,
ingo@388: String facet,
ingo@347: Document attributes,
ingo@347: CallContext context)
ingo@347: throws IOException
ingo@347: {
ingo@350: log.debug("FLYSArtifactCollection.doOut: " + outName);
ingo@347:
ingo@347: ThemeList themeList = new ThemeList(attributes);
ingo@347:
ingo@347: int size = themeList.size();
ingo@347: log.debug("Output will contain " + size + " elements.");
ingo@347:
ingo@347: try {
ingo@347: for (int i = 0; i < size; i++) {
ingo@347: ManagedFacet theme = themeList.get(i);
ingo@347:
ingo@347: if (theme == null) {
ingo@370: log.debug("Theme is empty - no output is generated.");
ingo@347: continue;
ingo@347: }
ingo@347:
ingo@347: String art = theme.getArtifact();
ingo@347:
ingo@347: if (log.isDebugEnabled()) {
ingo@347: log.debug("Do output for...");
ingo@347: log.debug("... artifact: " + art);
ingo@347: log.debug("... facet: " + theme.getName());
ingo@347: }
ingo@347:
ingo@364: String facetName = theme.getName();
ingo@364:
ingo@388: if (outName.equals("export") && !facetName.equals(facet)) {
ingo@388: continue;
ingo@388: }
ingo@388:
ingo@412: // TODO Remove the following two lines of code! The master
ingo@412: // artifact has to be determined correctly after
ingo@412: // OutGenerator.init is called!
ingo@412: Artifact artifact = getArtifact(art, context);
ingo@412: generator.setMasterArtifact(artifact);
ingo@412:
ingo@640: if (theme.getActive() == 0) {
ingo@640: continue;
ingo@640: }
ingo@640:
ingo@347: generator.doOut(
ingo@412: artifact,
ingo@364: facetName,
ingo@350: getFacetThemeFromAttribute(
ingo@350: art,
ingo@350: outName,
ingo@364: facetName,
ingo@350: context));
ingo@300: }
ingo@300: }
ingo@300: catch (ArtifactDatabaseException ade) {
ingo@300: log.error(ade, ade);
ingo@300: }
ingo@300:
ingo@300: generator.generate();
ingo@300: }
ingo@300:
ingo@300:
ingo@346: protected Document buildAttributes(
ingo@346: ArtifactDatabase db,
ingo@346: CallContext context,
ingo@346: Document oldAttr,
ingo@346: String[] items)
ingo@346: {
ingo@346: Document doc = XMLUtils.newDocument();
ingo@346:
ingo@346: XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
ingo@346: doc,
ingo@346: ArtifactNamespaceContext.NAMESPACE_URI,
ingo@346: ArtifactNamespaceContext.NAMESPACE_PREFIX);
ingo@346:
ingo@346: AttributeParser aParser = new AttributeParser();
ingo@346: OutputParser oParser = new OutputParser(db, context.getMeta());
ingo@346:
ingo@346: for (String uuid: items) {
ingo@346: try {
ingo@346: oParser.parse(uuid);
ingo@346: }
ingo@346: catch (ArtifactDatabaseException ade) {
ingo@346: log.warn(ade, ade);
ingo@346: }
ingo@346: }
ingo@346:
ingo@346: aParser.parse(oldAttr);
ingo@346:
ingo@346: return new AttributeWriter(aParser.getOuts(), oParser.getOuts()).write();
ingo@346: }
ingo@346:
ingo@346:
ingo@300: /**
ingo@347: * Returns the attribute for a specific output type.
ingo@347: *
ingo@347: * @param output The name of the desired output type.
ingo@347: *
ingo@347: * @return the attribute for the desired output type.
ingo@347: */
ingo@347: protected Document getAttribute(CallContext context, String output)
ingo@347: throws ArtifactDatabaseException
ingo@347: {
ingo@347: Document attr = buildAttributes(
ingo@347: context.getDatabase(),
ingo@347: context,
ingo@347: getAttribute(),
ingo@347: getArtifactUUIDs(context));
ingo@347:
ingo@347: Node out = (Node) XMLUtils.xpath(
ingo@347: attr,
ingo@638: "art:attribute/art:outputs/art:output[@name='" + output + "']",
ingo@347: XPathConstants.NODE,
ingo@347: ArtifactNamespaceContext.INSTANCE);
ingo@347:
ingo@347:
ingo@347: if (out != null) {
ingo@347: Document o = XMLUtils.newDocument();
ingo@347:
ingo@347: o.appendChild(o.importNode(out, true));
ingo@347:
ingo@347: return o;
ingo@347: }
ingo@347:
ingo@347: return null;
ingo@347: }
ingo@347:
ingo@347:
ingo@347: /**
ingo@300: * This method returns the list of artifact UUIDs that this collections
ingo@300: * contains.
ingo@300: *
ingo@300: * @param context The CallContext that is necessary to get information about
ingo@300: * the ArtifactDatabase.
ingo@300: *
ingo@300: * @return a list of uuids.
ingo@300: */
ingo@300: protected String[] getArtifactUUIDs(CallContext context)
ingo@300: throws ArtifactDatabaseException
ingo@300: {
ingo@300: log.debug("FLYSArtifactCollection.getArtifactUUIDs");
ingo@300:
ingo@300: ArtifactDatabase db = context.getDatabase();
ingo@300: CallMeta meta = context.getMeta();
ingo@300:
ingo@300: Document itemList = db.listCollectionArtifacts(identifier(), meta);
ingo@300: NodeList items = (NodeList) XMLUtils.xpath(
ingo@300: itemList,
ingo@300: XPATH_COLLECTION_ITEMS,
ingo@300: XPathConstants.NODESET,
ingo@300: ArtifactNamespaceContext.INSTANCE);
ingo@300:
ingo@300: if (items == null || items.getLength() == 0) {
ingo@300: log.debug("No artifacts found in this collection.");
ingo@300: return null;
ingo@300: }
ingo@300:
ingo@300: int num = items.getLength();
ingo@300:
ingo@300: List uuids = new ArrayList(num);
ingo@300:
ingo@300: for (int i = 0; i < num; i++) {
ingo@300: String uuid = XMLUtils.xpathString(
ingo@300: items.item(i),
ingo@300: "@art:uuid",
ingo@300: ArtifactNamespaceContext.INSTANCE);
ingo@300:
ingo@300: if (uuid != null && uuid.trim().length() != 0) {
ingo@300: uuids.add(uuid);
ingo@300: }
ingo@300: }
ingo@300:
ingo@300: return (String[]) uuids.toArray(new String[uuids.size()]);
ingo@300: }
ingo@300:
ingo@300:
ingo@300: /**
ingo@300: * Returns a concrete Artifact of this collection specified by its uuid.
ingo@300: *
ingo@300: * @param uuid The Artifact's uuid.
ingo@300: * @param context The CallContext.
ingo@300: *
ingo@300: * @return an Artifact.
ingo@300: */
ingo@300: protected Artifact getArtifact(String uuid, CallContext context)
ingo@300: throws ArtifactDatabaseException
ingo@300: {
ingo@300: log.debug("FLYSArtifactCollection.getArtifact");
ingo@300:
ingo@300: Backend backend = Backend.getInstance();
ingo@300: PersistentArtifact persistent = backend.getArtifact(uuid);
ingo@300:
ingo@300: return persistent != null ? persistent.getArtifact() : null;
ingo@300: }
ingo@300:
ingo@300:
ingo@300: /**
ingo@300: * Returns the attribute that belongs to an artifact stored in this
ingo@300: * collection.
ingo@300: *
ingo@300: * @param uuid The Artifact's uuid.
ingo@350: * @param outname The name of the requested output.
ingo@350: * @param facet The name of the requested facet.
ingo@300: * @param context The CallContext.
ingo@300: *
ingo@300: * @return an attribute in form of a document.
ingo@300: */
ingo@350: protected Document getFacetThemeFromAttribute(
ingo@350: String uuid,
ingo@350: String outName,
ingo@350: String facet,
ingo@350: CallContext context)
ingo@300: throws ArtifactDatabaseException
ingo@300: {
ingo@350: log.debug("FLYSArtifactCollection.getFacetThemeFromAttribute");
ingo@300:
ingo@350: ArtifactDatabase db = context.getDatabase();
ingo@350: CallMeta meta = context.getMeta();
ingo@350:
ingo@350: FLYSContext flysContext = context instanceof FLYSContext
ingo@350: ? (FLYSContext) context
ingo@350: : (FLYSContext) context.globalContext();
ingo@350:
ingo@350: Map mappings = (Map)
ingo@350: flysContext.get(FLYSContext.THEME_MAPPING);
ingo@350:
ingo@350: String themeName = mappings.get(facet);
ingo@350:
ingo@350: Document attr = db.getCollectionItemAttribute(identifier(), uuid, meta);
ingo@350:
ingo@350: if (attr == null) {
ingo@350: attr = initItemAttribute(uuid, facet, context);
ingo@350:
ingo@350: if (attr == null) {
ingo@350: return null;
ingo@350: }
ingo@350: }
ingo@350:
ingo@350: log.debug("Search attribute of collection item: " + uuid);
ingo@350:
ingo@350: Node tmp = (Node) XMLUtils.xpath(
ingo@350: attr,
ingo@350: "/art:attribute",
ingo@350: XPathConstants.NODE,
ingo@350: ArtifactNamespaceContext.INSTANCE);
ingo@350:
ingo@350: if (tmp == null) {
ingo@350: log.warn("No attribute found. Operation failed.");
ingo@350: return null;
ingo@350: }
ingo@350:
ingo@350: log.debug("Search theme '" + themeName + "' in attribute.");
ingo@350:
ingo@350: Node theme = (Node) XMLUtils.xpath(
ingo@350: tmp,
ingo@350: "art:themes/theme[@name='" + themeName + "']",
ingo@350: XPathConstants.NODE,
ingo@350: ArtifactNamespaceContext.INSTANCE);
ingo@350:
ingo@350: if (theme == null) {
ingo@350: log.warn("Could not find the theme in attribute of: " + uuid);
ingo@350:
ingo@350: Theme t = getThemeForFacet(uuid, facet, context);
ingo@350:
ingo@350: if (t == null) {
ingo@350: log.warn("No theme found for facet: " + facet);
ingo@350: return null;
ingo@350: }
ingo@350:
ingo@350: addThemeToAttribute(uuid, attr, t, context);
ingo@350: theme = t.toXML().getFirstChild();
ingo@350: }
ingo@350:
ingo@350: Document doc = XMLUtils.newDocument();
ingo@350: doc.appendChild(doc.importNode(theme, true));
ingo@350:
ingo@350: return doc;
ingo@350: }
ingo@350:
ingo@350:
ingo@350: /**
ingo@350: * Adds the theme of a facet to a CollectionItem's attribute.
ingo@350: *
ingo@350: * @param uuid The uuid of the artifact.
ingo@350: * @param attr The current attribute of an artifact.
ingo@350: * @param t The theme to add.
ingo@350: * @param context The CallContext.
ingo@350: */
ingo@350: protected void addThemeToAttribute(
ingo@350: String uuid,
ingo@350: Document attr,
ingo@350: Theme t,
ingo@350: CallContext context)
ingo@350: {
ingo@350: log.debug("FLYSArtifactCollection.addThemeToAttribute: " + uuid);
ingo@350:
ingo@350: if (t == null) {
ingo@350: log.warn("Theme is empty - cancel adding it to attribute!");
ingo@350: return;
ingo@350: }
ingo@350:
ingo@350: XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
ingo@350: attr,
ingo@350: ArtifactNamespaceContext.NAMESPACE_URI,
ingo@350: ArtifactNamespaceContext.NAMESPACE_PREFIX);
ingo@350:
ingo@350: Node tmp = (Node) XMLUtils.xpath(
ingo@350: attr,
ingo@350: "/art:attribute",
ingo@350: XPathConstants.NODE,
ingo@350: ArtifactNamespaceContext.INSTANCE);
ingo@350:
ingo@350: if (tmp == null) {
ingo@350: tmp = ec.create("attribute");
ingo@350: attr.appendChild(tmp);
ingo@350: }
ingo@350:
ingo@350: Node themes = (Node) XMLUtils.xpath(
ingo@350: tmp,
ingo@350: "art:themes",
ingo@350: XPathConstants.NODE,
ingo@350: ArtifactNamespaceContext.INSTANCE);
ingo@350:
ingo@350: if (themes == null) {
ingo@350: themes = ec.create("themes");
ingo@350: tmp.appendChild(themes);
ingo@350: }
ingo@350:
ingo@350: themes.appendChild(attr.importNode(t.toXML().getFirstChild(), true));
ingo@350:
ingo@350: try {
ingo@350: setCollectionItemAttribute(uuid, attr, context);
ingo@350:
ingo@350: log.debug("Successfully added theme to item attribute.");
ingo@350: }
ingo@350: catch (ArtifactDatabaseException e) {
ingo@350: // do nothing
ingo@350: log.warn("Cannot set attribute of item: " + uuid);
ingo@350: }
ingo@350: }
ingo@350:
ingo@350:
ingo@350: /**
ingo@350: * Initializes the attribute of an collection item with the theme of a
ingo@350: * specific facet.
ingo@350: *
ingo@350: * @param uuid The uuid of an artifact.
ingo@350: * @param facet The name of a facet.
ingo@350: * @param context The CallContext.
ingo@350: *
ingo@350: * @param the new attribute.
ingo@350: */
ingo@350: protected Document initItemAttribute(
ingo@350: String uuid,
ingo@350: String facet,
ingo@350: CallContext context)
ingo@350: {
ingo@350: log.info("FLYSArtifactCollection.initItemAttribute");
ingo@350:
ingo@350: Theme t = getThemeForFacet(uuid, facet, context);
ingo@350:
ingo@350: if (t == null) {
ingo@350: log.info("Could not find theme for facet. Cancel initialization.");
ingo@350: return null;
ingo@350: }
ingo@350:
ingo@350: Document attr = XMLUtils.newDocument();
ingo@350:
ingo@350: addThemeToAttribute(uuid, attr, t, context);
ingo@350:
ingo@350: return attr;
ingo@350: }
ingo@350:
ingo@350:
ingo@350: /**
ingo@350: * Sets the attribute of a CollectionItem specified by uuid to a new
ingo@350: * value attr.
ingo@350: *
ingo@350: * @param uuid The uuid of the CollectionItem.
ingo@350: * @param attr The new attribute for the CollectionItem.
ingo@350: * @param context The CallContext.
ingo@350: */
ingo@350: public void setCollectionItemAttribute(
ingo@350: String uuid,
ingo@350: Document attr,
ingo@350: CallContext context)
ingo@350: throws ArtifactDatabaseException
ingo@350: {
ingo@350: Document doc = ClientProtocolUtils.newSetItemAttributeDocument(
ingo@350: uuid,
ingo@350: attr);
ingo@350:
ingo@350: if (doc == null) {
ingo@350: log.warn("Cannot set item attribute: No attribute found.");
ingo@350: return;
ingo@350: }
ingo@350:
ingo@350: ArtifactDatabase db = context.getDatabase();
ingo@350: CallMeta meta = context.getMeta();
ingo@350:
ingo@350: db.setCollectionItemAttribute(identifier(), uuid, doc, meta);
ingo@350: }
ingo@350:
ingo@350:
ingo@350: /**
ingo@350: * Returns the theme of a specific facet.
ingo@350: *
ingo@350: * @param uuid The uuid of an artifact.
ingo@350: * @param facet The name of the facet.
ingo@350: * @param context The CallContext object.
ingo@350: *
ingo@350: * @return the desired theme.
ingo@350: */
ingo@350: protected Theme getThemeForFacet(
ingo@350: String uuid,
ingo@350: String facet,
ingo@350: CallContext context)
ingo@350: {
ingo@350: log.info("FLYSArtifactCollection.getThemeForFacet: " + facet);
ingo@350:
ingo@350: FLYSContext flysContext = context instanceof FLYSContext
ingo@350: ? (FLYSContext) context
ingo@350: : (FLYSContext) context.globalContext();
ingo@350:
ingo@350: return ThemeFactory.getTheme(flysContext, facet);
ingo@300: }
ingo@300:
ingo@300:
ingo@300: /**
ingo@300: * Returns the OutGenerator for a specified type.
ingo@300: *
ingo@300: * @param name The name of the output type.
ingo@300: * @param type Defines the type of the desired OutGenerator.
ingo@300: *
ingo@300: * @return The OutGenerator specified by type.
ingo@300: */
ingo@300: protected OutGenerator getOutGenerator(
ingo@300: CallContext context,
ingo@300: String name,
ingo@300: String type)
ingo@300: {
ingo@300: FLYSContext flysContext = context instanceof FLYSContext
ingo@300: ? (FLYSContext) context
ingo@300: : (FLYSContext) context.globalContext();
ingo@300:
ingo@300: Map generators = (Map)
ingo@300: flysContext.get(FLYSContext.OUTGENERATORS_KEY);
ingo@300:
ingo@300: if (generators == null) {
ingo@300: log.error("No output generators found in the running application!");
ingo@300: return null;
ingo@300: }
ingo@300:
ingo@388: Class clazz = generators.get(name);
ingo@300:
ingo@300: try {
ingo@300: return clazz != null ? (OutGenerator) clazz.newInstance() : null;
ingo@300: }
ingo@300: catch (InstantiationException ie) {
ingo@300: log.error(ie, ie);
ingo@300: }
ingo@300: catch (IllegalAccessException iae) {
ingo@300: log.error(iae, iae);
ingo@300: }
ingo@300:
ingo@300: return null;
ingo@300: }
ingo@300:
ingo@300:
ingo@147: protected Element buildArtifactNode(
ingo@293: ArtifactDatabase database,
ingo@293: String uuid,
ingo@147: CallContext context,
ingo@147: XMLUtils.ElementCreator ec)
ingo@293: throws ArtifactDatabaseException
ingo@147: {
ingo@293: log.debug("Append artifact '" + uuid + "' to collection description");
ingo@147:
ingo@346: // TODO
ingo@293: String hash = "MYHASH";
ingo@156:
ingo@147: Element ci = ec.create("artifact");
ingo@148: ec.addAttr(ci, "uuid", uuid, true);
ingo@293: ec.addAttr(ci, "hash", hash, true);
ingo@147:
ingo@346: // XXX I am not sure if it works well every time with an empty document
ingo@346: // in the describe operation of an artifact.
ingo@346: Document description = database.describe(uuid, null, context.getMeta());
ingo@346:
ingo@293: Node outputModes = (Node) XMLUtils.xpath(
ingo@147: description,
ingo@147: XPATH_ARTIFACT_OUTPUTMODES,
ingo@147: XPathConstants.NODE,
ingo@147: ArtifactNamespaceContext.INSTANCE);
ingo@147:
ingo@147: if (outputModes != null) {
ingo@147: Document doc = ci.getOwnerDocument();
ingo@147: ci.appendChild(doc.importNode(outputModes, true));
ingo@147: }
ingo@147:
ingo@147: return ci;
ingo@147: }
ingo@347:
ingo@347:
ingo@347: /**
ingo@347: * Inner class to structure/order the themes of a chart.
ingo@347: */
ingo@347: private class ThemeList {
ingo@347: private Logger logger = Logger.getLogger(ThemeList.class);
ingo@638: protected Map themes;
ingo@347:
ingo@347: public ThemeList(Document output) {
ingo@638: themes = new HashMap();
ingo@347: parse(output);
ingo@347: }
ingo@347:
ingo@347: protected void parse(Document output) {
ingo@347: NodeList themes = (NodeList) XMLUtils.xpath(
ingo@347: output,
ingo@347: "art:output/art:theme",
ingo@347: XPathConstants.NODESET,
ingo@347: ArtifactNamespaceContext.INSTANCE);
ingo@347:
ingo@347: int num = themes != null ? themes.getLength() : 0;
ingo@347:
ingo@347: logger.debug("Output has " + num + " elements.");
ingo@347:
ingo@347: if (num == 0) {
ingo@347: return;
ingo@347: }
ingo@347:
ingo@347: for (int i = 0; i < num; i++) {
ingo@347: Node theme = themes.item(i);
ingo@347:
ingo@347: String name = XMLUtils.xpathString(
ingo@347: theme, "@art:facet", ArtifactNamespaceContext.INSTANCE);
ingo@347:
ingo@347: String uuid = XMLUtils.xpathString(
ingo@347: theme, "@art:artifact", ArtifactNamespaceContext.INSTANCE);
ingo@347:
ingo@347: String pos = XMLUtils.xpathString(
ingo@347: theme, "@art:pos", ArtifactNamespaceContext.INSTANCE);
ingo@347:
ingo@347: String active = XMLUtils.xpathString(
ingo@347: theme, "@art:active", ArtifactNamespaceContext.INSTANCE);
ingo@347:
ingo@347: addTheme(uuid, name, pos, active);
ingo@347: }
ingo@347: }
ingo@347:
ingo@347: protected void addTheme(
ingo@347: String uuid,
ingo@347: String name,
ingo@347: String position,
ingo@347: String active)
ingo@347: {
ingo@347: if (logger.isDebugEnabled()) {
ingo@347: logger.debug("Add theme: ");
ingo@347: logger.debug(".. name: " + name);
ingo@347: logger.debug(".. uuid: " + uuid);
ingo@347: logger.debug(".. position: " + position);
ingo@347: logger.debug(".. active: " + active);
ingo@347: }
ingo@347:
ingo@347: try {
ingo@370: int pos = Integer.parseInt(position);
ingo@370: int act = Integer.parseInt(active);
ingo@347:
ingo@638: themes.put(
ingo@638: new Integer(pos-1),
ingo@638: new ManagedFacet(name, null, uuid, pos, act));
ingo@347: }
ingo@347: catch (NumberFormatException nfe) {
ingo@370: logger.warn(nfe, nfe);
ingo@347: }
ingo@347: }
ingo@347:
ingo@347: public ManagedFacet get(int idx) {
ingo@638: return themes.get(new Integer(idx));
ingo@347: }
ingo@347:
ingo@347: public int size() {
ingo@347: return themes.size();
ingo@347: }
ingo@347: }
ingo@147: }
ingo@147: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :