/* See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * Esri Inc. licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.esri.gpt.catalog.schema; import com.esri.gpt.catalog.discovery.PropertyMeaning; import com.esri.gpt.catalog.discovery.PropertyMeanings; import com.esri.gpt.catalog.gxe.GxeContext; import com.esri.gpt.catalog.gxe.GxeDefinition; import com.esri.gpt.catalog.gxe.GxeLoader; import com.esri.gpt.catalog.schema.indexable.IndexableContext; import com.esri.gpt.catalog.schema.indexable.Indexables; import com.esri.gpt.framework.geometry.Envelope; import com.esri.gpt.framework.jsf.FacesContextBroker; import com.esri.gpt.framework.jsf.components.LiveDataTag; import com.esri.gpt.framework.jsf.components.UILiveData; import com.esri.gpt.framework.util.Val; import com.esri.gpt.framework.xml.DomUtil; import com.esri.gpt.framework.xml.XsltTemplates; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.faces.component.UIComponent; import javax.faces.component.html.HtmlOutputText; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.w3c.dom.*; import org.xml.sax.SAXException; /** * Defines a metadata schema. */ public class Schema extends Component { // class variables ============================================================= private static Logger LOGGER = Logger.getLogger(Schema.class.getName()); private static XsltTemplates XSLTTEMPLATES = new XsltTemplates(); // instance variables ========================================================== private String _activeDocumentXml; private String _cswBriefXslt = ""; private String _cswOutputSchema = ""; private String _cswSummaryXslt = ""; private String _detailsXslt = ""; private boolean _editable = true; private EsriTags _evaluatedEsriTags = null; private GxeDefinition _gxeEditorDefinition; private Indexables _indexables; private Interrogation _interrogation; private Label _label; private Meaning _meaning; private Namespaces _namespaces; private PropertyMeanings _propertyMeanings = new PropertyMeanings(); private String _schematronXslt = ""; private Sections _sections; private String _templateFile = ""; private String _toEsriXslt = ""; private ValidationErrors _validationErrors; private String _xsdLocation = ""; private String _toEsriItemInfoXslt = ""; // constructors ================================================================ /** Default constructor. */ public Schema() { this(null); } /** * Construct by duplicating an existing object. * @param objectToDuplicate the object to duplicate */ public Schema(Schema objectToDuplicate) { super(objectToDuplicate); if (objectToDuplicate == null) { setMeaning(new Meaning(this._propertyMeanings)); setNamespaces(new Namespaces()); setInterrogation(new Interrogation()); setSections(new Sections()); } else { setPropertyMeanings(objectToDuplicate.getPropertyMeanings()); setEditable(objectToDuplicate.getEditable()); setTemplateFile(objectToDuplicate.getTemplateFile()); setCswBriefXslt(objectToDuplicate.getCswBriefXslt()); setCswOutputSchema(objectToDuplicate.getCswOutputSchema()); setCswSummaryXslt(objectToDuplicate.getCswSummaryXslt()); setDetailsXslt(objectToDuplicate.getDetailsXslt()); setToEsriXslt(objectToDuplicate.getToEsriXslt()); setXsdLocation(objectToDuplicate.getXsdLocation()); setMeaning(new Meaning(this._propertyMeanings)); setNamespaces(new Namespaces(objectToDuplicate.getNamespaces())); setInterrogation(objectToDuplicate.getInterrogation().duplicate()); setSchematronXslt(objectToDuplicate.getSchematronXslt()); setSections(new Sections(objectToDuplicate.getSections(), null)); if (objectToDuplicate.getLabel() != null) { setLabel(objectToDuplicate.getLabel().duplicate()); } if (objectToDuplicate.getIndexables() != null) { setIndexables(new Indexables(objectToDuplicate.getIndexables())); } if (objectToDuplicate.getGxeEditorDefinition() != null) { setGxeEditorDefinition(objectToDuplicate.getGxeEditorDefinition()); } setToEsriItemInfoXslt(objectToDuplicate.getToEsriItemInfoXslt()); } } // properties ================================================================== /** * Gets the XML associated with the metadata document that was most recently * evaluated for this schema. * @return the XML */ public String getActiveDocumentXml() { return _activeDocumentXml; } /** * Sets the XML associated with the metadata document that was most recently * evaluated for this schema. * @param xml the XML */ public void setActiveDocumentXml(String xml) { _activeDocumentXml = xml; } /** * Gets the XSLT (file path) for generating the brief CSW response (optional). * <br/>Only applies if the document can generate non Dublin Core responses. * @return the file path to the brief XSLT */ public String getCswBriefXslt() { return _cswBriefXslt; } /** * Sets the XSLT (file path) for generating the brief CSW response (optional). * <br/>Only applies if the document can generate non Dublin Core responses. * @param xslt the file path to the brief XSLT */ public void setCswBriefXslt(String xslt) { _cswBriefXslt = Val.chkStr(xslt); } /** * Gets the CSW output schema (namespace) associated with the document. * <br/>Only applies if the document can generate non Dublin Core responses. * @return the CSW output schema */ public String getCswOutputSchema() { return _cswOutputSchema; } /** * Sets the CSW output schema (namespace) associated with the document. * <br/>Only applies if the document can generate non Dublin Core responses. * @param namespace the CSW output schema */ public void setCswOutputSchema(String namespace) { _cswOutputSchema = Val.chkStr(namespace); } /** * Gets the XSLT (file path) for generating the summary CSW response (optional). * <br/>Only applies if the document can generate non Dublin Core responses. * @return the file path to the summary XSLT */ public String getCswSummaryXslt() { return _cswSummaryXslt; } /** * Sets the XSLT (file path) for generating the summary CSW response (optional). * <br/>Only applies if the document can generate non Dublin Core responses. * @param xslt the file path to the summary XSLT */ public void setCswSummaryXslt(String xslt) { _cswSummaryXslt = Val.chkStr(xslt); } /** * Gets the XSLT (file path) for displaying metadata details (as HTML). * @return the file path to the details XSLT */ public String getDetailsXslt() { return _detailsXslt; } /** * Sets the XSLT (file path) for displaying metadata details (as HTML). * @param xslt the file path to the details XSLT */ public void setDetailsXslt(String xslt) { _detailsXslt = Val.chkStr(xslt); } /** * Gets the editable status. * @return true if this schema is editable within the metadata editor */ public boolean getEditable() { return _editable; } /** * Sets the editable status. * @param editable true if this schema is editable within the metadata editor */ public void setEditable(boolean editable) { _editable = editable; } /** * Gets the Geoportal XML editor definition (optional). * @return the editor definition */ public GxeDefinition getGxeEditorDefinition() { return _gxeEditorDefinition; } /** * Sets the Geoportal XML editor definition (optional). * @param definition the editor definition */ public void setGxeEditorDefinition(GxeDefinition definition) { _gxeEditorDefinition = definition; } /** * Gets the indexable properties. * @return the indexable properties */ public Indexables getIndexables() { return this._indexables; } /** * Sets the indexable properties. * @param indexables the indexable properties */ public void setIndexables(Indexables indexables) { this._indexables = indexables; } /** * Gets the interrogation component. * @return the interrogation component */ public Interrogation getInterrogation() { return _interrogation; } /** * Sets the interrogation component. * @param interrogation the interrogation component */ protected void setInterrogation(Interrogation interrogation) { _interrogation = interrogation; if (_interrogation == null) { _interrogation = new Interrogation(); } } /** * Gets the label component. * @return the label component */ public Label getLabel() { return _label; } /** * Sets the label component. * @param label the label component */ protected void setLabel(Label label) { _label = label; } /** * Gets the meaning component for the schema. * @return the meaning component */ public Meaning getMeaning() { return _meaning; } /** * Sets the meaning component for the schema. * @param meaning the meaning component */ private void setMeaning(Meaning meaning) { _meaning = meaning; } /** * Gets the namespaces for the schema. * @return the schema namespaces */ public Namespaces getNamespaces() { return _namespaces; } /** * Sets the namespaces for the schema. * @param namespaces the schema namespaces */ protected void setNamespaces(Namespaces namespaces) { _namespaces = namespaces; if (_namespaces == null) { _namespaces = new Namespaces(); } } /** * Gets the configured property meanings. * @return the property meanings */ protected PropertyMeanings getPropertyMeanings() { return _propertyMeanings; } /** * Sets the configured property meanings. * @param meanings the property meanings */ protected void setPropertyMeanings(PropertyMeanings meanings) { this._propertyMeanings = meanings; } /** * Gets the XSLT (file path) used to perform Schematron validation. * <p/> * If supplied, the metadata document will be validated prior to publication. * <br/>The XSLT must produce an SVRL document (Schematron Validation Report Language). * @return the file path to the XSLT */ public String getSchematronXslt() { return this._schematronXslt; } /** * Sets the XSLT (file path) used to perform Schematron validation. * <p/> * If supplied, the metadata document will be validated prior to publication. * <br/>The XSLT must produce an SVRL document (Schematron Validation Report Language). * @param xslt the file path to the XSLT */ public void setSchematronXslt(String xslt) { this._schematronXslt = Val.chkStr(xslt); } /** * Gets XSLT (file path) used to perform to ESRI_ItemInformation transformation. * @return XSLT file path */ public String getToEsriItemInfoXslt() { return _toEsriItemInfoXslt; } /** * Sets XSLT (file path) used to perform to ESRI_ItemInformation transformation. * @param xslt XSLT file path */ public void setToEsriItemInfoXslt(String xslt) { this._toEsriItemInfoXslt = Val.chkStr(xslt); } /** * Gets the sections for the schema. * @return the schema sections */ public Sections getSections() { return _sections; } /** * Sets the sections for the schema. * @param sections the schema sections */ protected void setSections(Sections sections) { _sections = sections; if (_sections == null) { _sections = new Sections(); } } /** * Gets the template file path. * <p/> * The template is an XML file used for the creation and editing of * metadata documents for this schema. * @return the template file */ public String getTemplateFile() { return _templateFile; } /** * Sets the template file path. * <p/> * The template is an XML file used for the creation and editing of * metadata documents for this schema. * @param templateFile the template file */ public void setTemplateFile(String templateFile) { _templateFile = Val.chkStr(templateFile); } /** * Gets the XSLT (file path) for translating to an ESRI format. * <p/> * When a schema is neither FGDC or EsriIso, the document must * be translated to an ESRI format enclosed as a binary node prior * to publishing to the ArcIMS metdata server. * @return the file path to the XSLT */ public String getToEsriXslt() { return _toEsriXslt; } /** * Sets the XSLT (file path) for translating to an ESRI format. * <p/> * When a schema is neither FGDC or EsriIso, the document must * be translated to an ESRI format enclosed as a binary node prior * to publishing to the ArcIMS metdata server. * @param xslt the file path to the XSLT */ public void setToEsriXslt(String xslt) { _toEsriXslt = Val.chkStr(xslt); } /** * Gets the validation errors. * @return the schema sections */ public ValidationErrors getValidationErrors() { return _validationErrors; } /** * Sets the validation errors. * @param errors validation errors */ protected void setValidationErrors(ValidationErrors errors) { _validationErrors = errors; if (_validationErrors == null) { _validationErrors = new ValidationErrors(); } } /** * Gets the location of the XML Schema definition file for the metadata standard. * <p/> * Not all metadata standards will have an XSD. If supplied, the * metadata document will be validated against the XSD pror to * publication. * @return the XSD location (URL) */ public String getXsdLocation() { return _xsdLocation; } /** * Sets the location of the XML Schema definition file for the metadata standard. * <p/> * Not all metadata standards will have an XSD. If supplied, the * metadata document will be validated against the XSD pror to * publication. * @param url the XSD location (URL) */ public void setXsdLocation(String url) { _xsdLocation = Val.chkStr(url); } // methods ===================================================================== /** * Appends all sections of the schema to the sections component of the * metadata details page. * @param context the UI context * @param sectionsComponent the sections component of the metadata details page */ public void appendDetailSections(UiContext context, UIComponent sectionsComponent) { appendEnvelopeArray(sectionsComponent); boolean liveDataSection = false; for (Section section : getSections().values()) { section.appendDetailComponents(this, context, sectionsComponent); if (section.getKey().equalsIgnoreCase("identification") && !liveDataSection) { liveDataSection = true; //appendLiveDataSection(sectionsComponent); } } if (!liveDataSection) { liveDataSection = true; //appendLiveDataSection(sectionsComponent); } assureComponentsIds(sectionsComponent); } /** * Appends all sections of the schema to the metadata editor sections component. * @param context the UI context * @param sectionsComponent the sections component of the metadata editor */ public void appendEditorSections(UiContext context, UIComponent sectionsComponent) { appendEnvelopeArray(sectionsComponent); for (Section section : getSections().values()) { section.appendEditorComponents(this, context, sectionsComponent); } assureComponentsIds(sectionsComponent); } /** * Appends the Array of envelope coodinates as a script. * @param sectionsComponent the active UI component for the section */ @SuppressWarnings("unchecked") private void appendEnvelopeArray(UIComponent sectionsComponent) { String[] aEnvIds = {"", "", "", ""}; findEnvelopeIds(getSections(), aEnvIds); String sEnvIds = "'" + aEnvIds[0] + "','" + aEnvIds[1] + "','" + aEnvIds[2] + "','" + aEnvIds[3] + "'"; String sScript = "<script>var mdeEnvelopeIds = new Array(" + sEnvIds + ");</script>"; HtmlOutputText script = new HtmlOutputText(); script.setEscape(false); script.setValue(sScript); sectionsComponent.getChildren().add(script); } /** * Appends live data section. * @param sectionsComponent the active UI component for the section */ @SuppressWarnings("unchecked") private void appendLiveDataSection(UIComponent sectionsComponent) { FacesContextBroker broker = new FacesContextBroker(); String contextPath = broker.extractHttpServletRequest().getContextPath(); String imgOpen = contextPath + "/catalog/images/section_open.gif"; String imgClosed = contextPath + "/catalog/images/section_closed.gif"; String caption = broker.extractMessageBroker().retrieveMessage("catalog.search.viewMetadataDetails.liveData"); String sScript = "<script>" + "function onCreatePlaceholder(node) {" + "node.innerHTML = \"<span class=\\\"section\\\">" + "<table class=\\\"sectionHeader\\\" summary=\\\"This table is for design purposes only.\\\" onclick=\\\"gpt.LiveData.onClickHandler('\" +node.id+ \"','" +imgOpen+ "','" +imgClosed+ "')\\\">" + "<tr>" + "<td>" + "<input type=\\\"checkbox\\\" style=\\\"display: none;\\\" id=\\\"\" +node.id+\"-chk\\\"/>"+ "</td>"+ "<td>"+ "<img src=\\\"" +imgOpen+ "\\\" id=\\\"\" +node.id+\"-img\\\"/>"+ "</td>"+ "<td>"+ "<span class=\\\"sectionCaption\\\" >"+ caption + "</span>"+ "</td>"+ "</tr>"+ "</table>"+ "<table class=\\\"sectionBody\\\" summary=\\\"This table is for design purposes only.\\\" id=\\\"\" +node.id+\"-body\\\">"+ "<tr><td id=\\\"\" +node.id+\"-cell\\\"></td></tr>" + "</table>"+ "</span>\";"+ "return dojo.byId(node.id+\"-cell\"); }" + "</script>"; HtmlOutputText script = new HtmlOutputText(); script.setEscape(false); script.setValue(sScript); sectionsComponent.getChildren().add(script); LiveDataTag liveDataTag = new LiveDataTag(); liveDataTag.setUrl(getMeaning().getResourceUrl()); liveDataTag.setOnCreatePlaceholder("onCreatePlaceholder"); UILiveData uiLiveData = new UILiveData(); liveDataTag.setProperties(uiLiveData); sectionsComponent.getChildren().add(uiLiveData); } /** * Configures the object based upon a node loaded from a * schema configuration XML. * <br/>The super.configure method should be invoked prior to any * sub-class configuration. * <p/> * The following attributes are configured: * <br/>key editable templateFile detailsXslt cswOutputSchema cswBriefXslt cswSummaryXslt xsdLocation * <p/> * The following child nodes are configured: * <br/>label namespace[] interrogation section[] * @param context the configuration context * @param node the configuration node * @param attributes the attributes of the configuration node */ @Override public void configure(CfgContext context, Node node, NamedNodeMap attributes) { super.configure(context, node, attributes); // configure attributes setEditable(Val.chkBool(DomUtil.getAttributeValue(attributes, "editable"), true)); setTemplateFile(DomUtil.getAttributeValue(attributes, "templateFile")); setDetailsXslt(DomUtil.getAttributeValue(attributes, "detailsXslt")); setCswOutputSchema(DomUtil.getAttributeValue(attributes, "cswOutputSchema")); setCswBriefXslt(DomUtil.getAttributeValue(attributes, "cswBriefXslt")); setCswSummaryXslt(DomUtil.getAttributeValue(attributes, "cswSummaryXslt")); setToEsriXslt(DomUtil.getAttributeValue(attributes, "toEsriXslt")); setXsdLocation(DomUtil.getAttributeValue(attributes, "xsdLocation")); setSchematronXslt(DomUtil.getAttributeValue(attributes, "schematronXslt")); setToEsriItemInfoXslt(DomUtil.getAttributeValue(attributes, "toEsriItemInfoXslt")); // configure the label component setLabel(context.getFactory().newLabel(context, DomUtil.findFirst(node, "label"))); // configure the namespace components Node[] aryNamespaces = DomUtil.findChildren(node, "namespace"); for (Node ndNamespace : aryNamespaces) { getNamespaces().add(context.getFactory().newNamespace(context, ndNamespace)); } // configure the interrogation component setInterrogation(context.getFactory().newInterrogation( context, DomUtil.findFirst(node, "interrogation"))); // configure the section components Node[] arySections = DomUtil.findChildren(node, "section"); for (Node ndSection : arySections) { getSections().add(context.getFactory().newSection(context, ndSection)); } getSections().checkExclusiveOpenStatus(); // indexable properties, XML editor settings NodeList nl = node.getChildNodes(); for (int i=0;i<nl.getLength();i++) { Node nd = nl.item(i); if (nd.getNodeType() == Node.ELEMENT_NODE) { String nodeName = Val.chkStr(nd.getNodeName()); if (nodeName.equalsIgnoreCase("indexables")) { Indexables idxables = new Indexables(); idxables.configure(context,nd,nd.getAttributes()); if (idxables.hasPropertiesOrSiblings()) { if (this.getIndexables() == null) { this.setIndexables(idxables); } else { this.getIndexables().addSibling(idxables); } } } else if (nodeName.equalsIgnoreCase("editor")) { String sLoc = Val.chkStr(DomUtil.getAttributeValue(nd.getAttributes(),"fileName")); if (sLoc.length() > 0) { GxeDefinition gxeDefinition = new GxeDefinition(); gxeDefinition.setKey(this.getKey()); gxeDefinition.setFileLocation(sLoc); this.setGxeEditorDefinition(gxeDefinition); GxeContext gxeContext = new GxeContext(); GxeLoader gxeLoader = new GxeLoader(); try { gxeLoader.loadDefinition(gxeContext,gxeDefinition); } catch (Exception e) { LOGGER.log(Level.CONFIG,"Error loading GXE XML Editor definition.",e); } } } } } if (this.getIndexables() != null) { if (!this.getIndexables().hasPropertiesOrSiblings()) { this.setIndexables(null); } } } /** * Produces a deep clone of the object. * <br/>The duplication constructor is invoked. * <br/>return new Schema(this); */ public Schema duplicate() { return new Schema(this); } /** * Ensures the the minimal components of a schema. * <p/> * The schema should have been evaluated at some point prior to executing this method. * <br/>At the moment, this method doesn't throw exceptions. An empty title is set to "Untitled", * an invalid envelope is set to the extent of the world. */ public void ensureMinimals() { if (getMeaning().getTitle().length() == 0) { getMeaning().setTitle("Untitled"); } if (!getMeaning().getEnvelope().isValid()) { PropertyMeaning meaning = this.getPropertyMeanings().get("geometry"); if ((meaning != null) && (meaning instanceof PropertyMeaning.Geometry)) { Envelope def = ((PropertyMeaning.Geometry)meaning).getDefaultEnvelope(); if ((def != null) && def.isValid()) { getMeaning().getEnvelope().put(def.getMinX(),def.getMinY(),def.getMaxX(),def.getMaxY()); } } } String contentType = Val.chkStr(getMeaning().getArcIMSContentType()); if (contentType.length() == 0) { getMeaning().setArcIMSContentType("unknown"); } } /** * Evaluates a schema based upon the supplied metadata document. * <p/> * The default behavior is to invoke the "evaluate" method * for each section within the schema. * @param dom the metadata document * @throws XPathExpressionException if an evaluation expression fails */ public void evaluate(Document dom) throws XPathExpressionException { NamespaceContextImpl ns = new NamespaceContextImpl(getNamespaces()); XPath xpath = XPathFactory.newInstance().newXPath(); xpath.setNamespaceContext(ns); for (Section section : getSections().values()) { section.evaluate(this,dom,xpath); } getSections().checkExclusiveOpenStatus(); _evaluatedEsriTags = new EsriTags(); _evaluatedEsriTags.evaluate(this,dom); getMeaning().applyEsriTags(this,_evaluatedEsriTags); if (this.getIndexables() != null) { IndexableContext ictx = new IndexableContext(this.getPropertyMeanings()); this.getIndexables().setIndexableContext(ictx); this.getIndexables().evaluate(this,ictx,dom,xpath); ictx.resolve(this,dom,_evaluatedEsriTags); } /* try { com.esri.gpt.catalog.classification.ClsConfig ccfg = new com.esri.gpt.catalog.classification.ClsConfig(); ccfg.configure(); com.esri.gpt.catalog.classification.ClsContext cctx = new com.esri.gpt.catalog.classification.ClsContext(); cctx.setConfig(ccfg); cctx.classify(dom,this); } catch (Exception e) { e.printStackTrace(); } */ } /** * Appends property information for the component to a StringBuffer. * <br/>The method is intended to support "FINEST" logging. * <br/>super.echo should be invoked prior appending any local information. * @param sb the StringBuffer to use when appending information */ @Override public void echo(StringBuffer sb) { super.echo(sb); sb.append(" editable=\"").append(getEditable()).append("\""); sb.append(" templateFile=\"").append(getTemplateFile()).append("\""); if (this.getCswOutputSchema().length() > 0) { sb.append(" cswOutputSchema=\"").append(this.getCswOutputSchema()).append("\""); } if (this.getCswBriefXslt().length() > 0) { sb.append(" cswBriefXslt=\"").append(this.getCswBriefXslt()).append("\""); } if (this.getCswSummaryXslt().length() > 0) { sb.append(" cswSummaryXslt=\"").append(this.getCswSummaryXslt()).append("\""); } if (getDetailsXslt().length() > 0) { sb.append(" detailsXslt=\"").append(getDetailsXslt()).append("\""); } if (getToEsriXslt().length() > 0) { sb.append(" toEsriXslt=\"").append(getToEsriXslt()).append("\""); } if (getXsdLocation().length() > 0) { sb.append(" xsdLocation=\"").append(getXsdLocation()).append("\""); } if (getSchematronXslt().length() > 0) { sb.append(" schematronXslt=\"").append(getSchematronXslt()).append("\""); } if (getToEsriItemInfoXslt().length() > 0) { sb.append(" toEsriItemInfoXslt=\"").append(getToEsriItemInfoXslt()).append("\""); } if (getLabel() != null) { sb.append("\n").append(getLabel()); } if ((getNamespaces() != null) && (getNamespaces().size() > 0)) { sb.append("\n").append(getNamespaces()); } sb.append("\n").append(getInterrogation()); sb.append("\n").append(getSections()); } /** * Finds the faces ids associated with the envelope input components. * @param sections the sections to check * @param ids (xmin-id,ymin-id,xmax-id,ymax-id) */ private void findEnvelopeIds(Sections sections, String[] ids) { for (Section section : sections.values()) { for (Parameter parameter : section.getParameters().values()) { Input input = parameter.getInput(); if (input != null) { String sMeaningType = parameter.getMeaningType(); if (sMeaningType.equals("")) { } else if (sMeaningType.equalsIgnoreCase(Meaning.MEANINGTYPE_ENVELOPE_EAST)) { ids[2] = input.getFacesId(); } else if (sMeaningType.equalsIgnoreCase(Meaning.MEANINGTYPE_ENVELOPE_NORTH)) { ids[3] = input.getFacesId(); } else if (sMeaningType.equalsIgnoreCase(Meaning.MEANINGTYPE_ENVELOPE_SOUTH)) { ids[1] = input.getFacesId(); } else if (sMeaningType.equalsIgnoreCase(Meaning.MEANINGTYPE_ENVELOPE_WEST)) { ids[0] = input.getFacesId(); } } } findEnvelopeIds(section.getSections(), ids); } } /** * Interrogates a schema based upon the supplied metadata document. * <p/> * The default behavior is to invoke the "interrogate" method * on the Interrogation object associated with the schema. * @param dom the metadata document * @return the interrogation object * @throws XPathExpressionException if an evaluation expression fails */ public Interrogation interrogate(Document dom) throws XPathExpressionException { NamespaceContextImpl ns = new NamespaceContextImpl(getNamespaces()); XPath xpath = XPathFactory.newInstance().newXPath(); xpath.setNamespaceContext(ns); getInterrogation().interrogate(this, dom, xpath); return getInterrogation(); } /** * Loads the template for this schema. * @return the XML document * @throws ParserConfigurationException if a configuration exception occurs * @throws SAXException if an exception occurs during XML parsing * @throws IOException if an i/o exception occurs */ public Document loadTemplate() throws ParserConfigurationException, SAXException, IOException { return DomUtil.makeDomFromResourcePath(getTemplateFile(), true); } /** * Updates the metadata document template based upon entered parameter value(s). * <p/> * The default behavior is to invoke the "update" method * for each section within the schema. * @param dom the metadata document template for the schema * @throws XPathExpressionException if an expression fails * @throws SchemaException if the update fails */ public void update(Document dom) throws XPathExpressionException, SchemaException { NamespaceContextImpl ns = new NamespaceContextImpl(getNamespaces()); XPath xpath = XPathFactory.newInstance().newXPath(); xpath.setNamespaceContext(ns); for (Section section : getSections().values()) { section.update(dom, xpath); } // update the rdf:about node based upon the resource url try { String rdfPfx = Val.chkStr(ns.getPrefix("http://www.w3.org/1999/02/22-rdf-syntax-ns#")); if (rdfPfx.length() > 0) { Node ndAbout = (Node)xpath.evaluate("/rdf:RDF/rdf:Description/@rdf:about",dom,XPathConstants.NODE); if (ndAbout != null) { String resUrl = ""; Node ndResUrl = (Node)xpath.evaluate("/rdf:RDF/rdf:Description/dct:references",dom,XPathConstants.NODE); if (ndResUrl != null) { resUrl = Val.chkStr(ndResUrl.getTextContent()); } if (resUrl.length() > 0) { ndAbout.setNodeValue(resUrl); } else { ((Attr)ndAbout).getOwnerElement().removeAttributeNode((Attr)ndAbout); } } } } catch (Exception eTmp) {} } /** * Triggered on the save event from the metadata editor. * <p/> * The default behavior is to invoke the "unBind" method for * the each section. * @param context the UI context * @param editorForm the Faces HtmlForm for the metadata editor * @throws SchemaException if an associated Faces UIComponent cannot be located */ public void unBind(UiContext context, UIComponent editorForm) throws SchemaException { for (Section section : getSections().values()) { section.unBind(this, context, editorForm); } } /** * Validates the schema. * <p/> * The default behavior is to invoke the "validate" method * for each section within the schema. * @throws ValidationException if errors occur during validation */ public void validate() throws ValidationException { setMeaning(new Meaning(this._propertyMeanings)); setValidationErrors(new ValidationErrors()); ValidationErrors errors = getValidationErrors(); for (Section section : getSections().values()) { section.validate(this); } if (_evaluatedEsriTags != null) { getMeaning().applyEsriTags(this, _evaluatedEsriTags); if (this.getIndexables() != null) { IndexableContext ictx = this.getIndexables().getIndexableContext(); if (ictx != null) { ictx.resolve(this,null,_evaluatedEsriTags); } } } if (errors.size() == 0) { ensureMinimals(); } // throw an exception if errors were encountered if (errors.size() > 0) { throw new ValidationException(getKey(), "Invalid metadata document.", errors); } } /** * Selects all parameters conforming to the condiditions defined by predicate. * @param predicate predicate * @return list of selected parameters */ public List<Parameter> selectParameters(Predicate predicate) { return getSections().selectParameters(predicate); } /** * Assures components ids. * @param parentComponent parent component */ private void assureComponentsIds(UIComponent parentComponent) { // find components with no id assigned ArrayList<UIComponent> components = new ArrayList<UIComponent>(); findComponentsWithNoId(components, parentComponent); // assign generated ids for (int i=0; i<components.size(); i++) { components.get(i).setId(parentComponent.getId()+"_genid_"+Integer.toString(i+1)); } } /** * Recursively finds components with no id assigned. * @param components collection of all components with unassigned id * @param parentComponent parent component */ private void findComponentsWithNoId(ArrayList<UIComponent> components, UIComponent parentComponent) { List children = parentComponent.getChildren(); for (int i=0; i<children.size(); i++) { UIComponent child = (UIComponent) children.get(i); if (Val.chkStr(child.getId()).length()==0) { components.add(child); } findComponentsWithNoId(components, child); } } }