Package com.esri.gpt.catalog.schema

Source Code of com.esri.gpt.catalog.schema.SchemaFactory

/* 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.PropertyMeanings;
import com.esri.gpt.framework.util.LogUtil;
import com.esri.gpt.framework.util.Val;
import com.esri.gpt.framework.xml.DomUtil;
import java.io.IOException;
import java.util.logging.Level;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

/**
* Provides a factory for instantiating schema component objects.
*/
public class SchemaFactory {

  // class variables =============================================================
   
  // instance variables ==========================================================
   
  // constructors ================================================================
 
  /** Default constructor. */
  public SchemaFactory() {}
 
  // properties ==================================================================
 
  // methods =====================================================================
 
  /**
   * Loads all property meanings from the gpt/metadata/property-meanings.xml configuration file.
   * @throws ParserConfigurationException if configuration exception occurs
   * @throws SAXException if an exception during xml parsing
   * @throws IOException if an i/o exception occurs
   * @throws ParserConfigurationException if error parsing configuration
   */
  public PropertyMeanings loadPropertyMeanings()
    throws ParserConfigurationException, SAXException, IOException {
    Document dom = DomUtil.makeDomFromResourcePath("gpt/metadata/property-meanings.xml",false);   
    PropertyMeanings meanings = new PropertyMeanings();
    try {
      meanings.load(dom);
    } catch (XPathExpressionException e) {
      throw new IOException(
          "An XPath expression failed while loading property-meanings.xml: "+e.getMessage());
    }
    return meanings;
  }
 
  /**
   * Loads the schemas contained within a file.
   * @param cgfContext the configuration conects
   * @param schemas the schema collection to populate
   * @param relativePath the relative path to the schema file
   * @throws ParserConfigurationException if configuration exception occurs
   * @throws SAXException if an exception during xml parsing
   * @throws IOException if an i/o exception occurs
   */
  private void loadSchemaFile(CfgContext cfgContext, Schemas schemas, String relativePath)
    throws ParserConfigurationException, SAXException, IOException {
       
    Document dom = DomUtil.makeDomFromResourcePath(relativePath,false);
    Node[] schemaNodes = null;
    Node ndContainer = DomUtil.findFirst(dom,"schemas");
    if (ndContainer != null) {
      schemaNodes = DomUtil.findChildren(ndContainer,"schema");
    } else {
      schemaNodes = DomUtil.findChildren(dom,"schema");
    }
   
    if (schemaNodes != null) {
      for (Node ndSchema: schemaNodes) {
        NamedNodeMap nnmSchema = ndSchema.getAttributes();
        String sFileName = Val.chkStr(DomUtil.getAttributeValue(nnmSchema,"fileName"));
        String sKey = Val.chkStr(DomUtil.getAttributeValue(nnmSchema,"sKey"));
        if (sFileName.length() > 0) {
      
          try {
            loadSchemaFile(cfgContext,schemas,sFileName);
          } catch (Exception e) {
            String sMsg = "Error loading metadata schema: "+sFileName;
            LogUtil.getLogger().log(Level.SEVERE,sMsg,e);
          }
        } else {
 
          try {
            Schema schema = cfgContext.getFactory().newSchema(schemas,cfgContext,ndSchema);
            schemas.add(schema);
          } catch (Exception e) {
            String sMsg = "Error loading metadata schema: "+relativePath+" , @key="+sKey;
            LogUtil.getLogger().log(Level.SEVERE,sMsg,e);
          }
         
        }
      }
    }
  }
   
  /**
   * Loads all schemas from the gpt/metadata/schema.xml configuration file.
   * @throws ParserConfigurationException if configuration exception occurs
   * @throws SAXException if an exception during xml parsing
   * @throws IOException if an i/o exception occurs
   */
  public Schemas loadSchemas()
    throws ParserConfigurationException, SAXException, IOException {
    CfgContext cfgContext = new CfgContext(this);
    PropertyMeanings meanings = loadPropertyMeanings();
    Schemas schemas = new Schemas();
    schemas.setPropertyMeanings(meanings);
    loadSchemaFile(cfgContext,schemas,"gpt/metadata/schemas.xml");   
    return schemas;
  }
 
  /**
   * Instantiates and configures a new Code component.
   * <br/>The node argument can be null, if so then return a null value.
   * @param context the configuration context
   * @param node the configuration node associated with the component
   * @return the new Code component (null if the node was invalid)
   */
  public Code newCode(CfgContext context, Node node) {
    if (node != null) {   
      Code component = new Code();
      component.configure(context,node,node.getAttributes());
      return component;
    }
    return null;
  }
 
  /**
   * Instantiates and configures a new Content component.
   * <br/>The node argument can be null, if so then return a null value.
   * @param context the configuration context
   * @param node the configuration node associated with the component
   * @return the new Content component (null if the node was invalid)
   */
  public Content newContent(CfgContext context, Node node) {
    if (node != null) {
      Content component = new Content();
      component.configure(context,node,node.getAttributes());
      return component;
    }
    return null;
  }
 
  /**
   * Instantiates and configures a new Label component.
   * <br/>The node argument can be null, if so then return a null value.
   * @param context the configuration context
   * @param node the configuration node associated with the component
   * @return the new Label component (null if the node was invalid)
   */
  public Input newInput(CfgContext context, Node node) {
    if (node != null) {
      Input component = null;
      String sType = DomUtil.getAttributeValue(node.getAttributes(),"type");
     
      // determine the input component type
      if (sType.equalsIgnoreCase(Input.INPUTTYPE_TEXT)) {
        component = new InputText();
      } el