Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* File: RelaxNGDataModel.java
* ************************************************************************
*
* ADOBE CONFIDENTIAL
* ___________________
*
* Copyright 2011 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.adobe.xmp.schema.rng.parser;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import com.adobe.xmp.schema.model.SchemaDescription;
import org.kohsuke.rngom.rngparser.ast.builder.BuildException;
import org.kohsuke.rngom.rngparser.ast.builder.SchemaBuilder;
import org.kohsuke.rngom.rngparser.ast.util.CheckingSchemaBuilder;
import org.kohsuke.rngom.rngparser.digested.DAnnotation;
import org.kohsuke.rngom.rngparser.digested.DGrammarPattern;
import org.kohsuke.rngom.rngparser.digested.DSchemaBuilderImpl;
import org.kohsuke.rngom.rngparser.parse.IllegalSchemaException;
import org.kohsuke.rngom.rngparser.parse.Parseable;
import org.kohsuke.rngom.rngparser.parse.xml.SAXParseable;
import org.w3c.dom.Element;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import com.adobe.xmp.schema.model.XMPSchemaException;
import com.adobe.xmp.schema.rng.model.PropertyInfo;
import com.adobe.xmp.schema.rng.model.SchemaInfo;
import com.adobe.xmp.schema.rng.parser.annotation.AnnotationsFactory;
import com.adobe.xmp.schema.rng.parser.annotation.RNGAnnotation;
import com.adobe.xmp.schema.rng.parser.annotation.RNGSchemaAnnotation;
import com.adobe.xmp.schema.rng.parser.exceptions.RNGInvalidSchemaException;
import com.adobe.xmp.schema.rng.parser.exceptions.RNGParseException;
import com.adobe.xmp.schema.rng.parser.generator.XMPSchemaGenerator;
import com.adobe.xmp.schema.rng.parser.traverser.GrammarWalker;
/**
* This class models a RelaxNG schema's data model as described by RelaxNG spec. This model can describe either a XMP packet composed
* of multiple XMP schemas or a single XMP schema. This class provides functionality to traverse the RelaxNG data model
* to construct the XMP schemas represeted by the model.
*
* @author hraghav
*/
@SuppressWarnings("rawtypes")
public class RelaxNGDataModel
{
private GrammarWalker visitor;
private DGrammarPattern grammar;
/**
* Construct a RelaxNGDataModel object from the input Grammar pattern.
*
* @param grammar
* @throws RNGParseException
*/
private RelaxNGDataModel(DGrammarPattern grammar) throws RNGParseException
{
this.grammar = grammar;
visitor = new GrammarWalker(grammar);
}
/**
* Construct a GrammarPattern from the RelaxNG schema which is represented by the inputsource is
*
* @param is
* InputSource representing the RelaxNG schema
* @param er
* A RelaxNG schema references and includes multiple other files. This enity resolver should define how
* these dependecies should be located by RelaxNG schema parser.
* @param eh
* ErrorHandler to handle error call backs generated by RelaxNG schema parser
* @return DGrammarPattern
* @throws RNGInvalidSchemaException
*/
@SuppressWarnings("unchecked")
static private DGrammarPattern constructGrammar(InputSource is, EntityResolver er, ErrorHandler eh)
throws RNGInvalidSchemaException
{
Parseable p = new SAXParseable(is, eh, er);
SchemaBuilder sb = new CheckingSchemaBuilder(new DSchemaBuilderImpl(), eh);
DGrammarPattern grammar = null;
try
{
grammar = (DGrammarPattern) p.parse(sb);
}
catch (BuildException e)
{
throw new RNGParseException("Exception occured while parsing input RelaxNG schema", e);
}
catch (IllegalSchemaException e)
{
throw new RNGInvalidSchemaException(e);
}
return grammar;
}
/**
* Construct a RelaxNGDataModel which models the input RelaxNG schema.
*
* @param rngFile
* File representing the RelaxNG schema
* @param er
* A RelaxNG schema references and includes multiple other files. This enity resolver should define how
* these dependecies should be located by RelaxNG schema parser.
* @return RelaxNGDataModel
* @throws RNGParseException
* If a exception occured while
* @throws RNGInvalidSchemaException
* If the input RelaxNg schema voilates RNG spec
* @throws IOException if rngFile cannot be resolved or loaded
* @throws MalformedURLException If URI is malformed
*/
static public RelaxNGDataModel newInstance(URI rngFile, EntityResolver er) throws RNGParseException,
RNGInvalidSchemaException, MalformedURLException, IOException
{
// RNGTODO provide a better default error handling or a sample doing the same
ErrorHandler eh = new DefaultHandler()
{
@Override
public void error(SAXParseException e) throws SAXException
{
throw e;
}
};
return newInstance(rngFile, er, eh);
}
/**
* Construct a RelaxNGDataModel which models the input RelaxNG schema.
*
* @param rngFile
* File representing the RelaxNG schema
* @param er
* A RelaxNG schema references and includes multiple other files. This entity resolver should define how
* these dependencies should be located by RelaxNG schema parser.
* @param eh
* ErrorHandler to handle error call backs generated by RelaxNG schema parser
* @return RelaxNGDataModel
* @throws RNGInvalidSchemaException
* If the input RelaxNg schema violates RNG spec
* @throws MalformedURLException If URI is malformed
* @throws IOException if rngFile cannot be resolved or loaded
*/
static public RelaxNGDataModel newInstance(URI rngFile, EntityResolver er, ErrorHandler eh)
throws RNGInvalidSchemaException, MalformedURLException, IOException
{
InputSource is = new InputSource(rngFile.toURL().openStream());
return newInstance(is, er, eh);
}
/**
* Construct a RelaxNGDataModel which models the input RelaxNG schema.
*
* @param is
* InputSource representing the RelaxNG schema
* @param er
* A RelaxNG schema references and includes multiple other files. This entity resolver should define how
* these dependencies should be located by RelaxNG schema parser.
* @return RelaxNGDataModel
* @throws RNGInvalidSchemaException
* If the input RelaxNg schema violates RNG spec
*/
static public RelaxNGDataModel newInstance(InputSource is, EntityResolver er)
throws RNGInvalidSchemaException
{
// RNGTODO provide a better default error handling or a sample doing the same
ErrorHandler eh = new DefaultHandler()
{
@Override
public void error(SAXParseException e) throws SAXException
{
throw e;
}
};
return newInstance(is, er, eh);
}
/**
* Construct a RelaxNGDataModel which models the input RelaxNG schema.
*
* @param is
* InputSource representing the RelaxNG schema
* @param er
* A RelaxNG schema references and includes multiple other files. This enity resolver should define how
* these dependecies should be located by RelaxNG schema parser.
* @param eh
* ErrorHandler to handle error call backs generated by RelaxNG schema parser
* @return RelaxNGDataModel
* @throws RNGInvalidSchemaException
* If the input RelaxNg schema voilates RNG spec
*/
static public RelaxNGDataModel newInstance(InputSource is, EntityResolver er, ErrorHandler eh)
throws RNGInvalidSchemaException
{
DGrammarPattern grammar = constructGrammar(is, er, eh);
return new RelaxNGDataModel(grammar);
}
/**
* Gets the schema which is represented by this RelaxNGDataModel
*
* @param handler
* This handler provides notifications for various events such as start, end of parsing a ref, start of
* property parsing, errors recieved while parsing property. This should not be null.
* @return First XMP schema from the list of XMP schemas represented by this RelaxNG schema
* @throws RNGParseException
* If a problem occured while traversing {@link RelaxNGDataModel} to form a {@link com.adobe.xmp.schema.model.SchemaDescription}
* object. This can happen if the input Relax NG schema does not correctly model a XMP schema.
* @throws XMPSchemaException
* Exception thrown for {@link com.adobe.xmp.schema.model.SchemaDescription} is propogated
*/
public SchemaDescription constructXMPSchema(SchemaGenerationHandler handler) throws RNGParseException,
XMPSchemaException
{
if (handler == null)
throw new IllegalArgumentException(
"ISchemaGenerationTraceHandler used for constructing schemas should not be null");
visitor.setSchemaGenerationHandler(handler);
grammar.accept(visitor);
ArrayList propInfoList = visitor.getPropInfoList();
if (propInfoList == null || propInfoList.size() == 0)
{
throw new RNGParseException("Schema files defined a schema without any properties.");
}
PropertyInfo firstProperty = propInfoList.get(0);
SchemaInfo info = firstProperty.getSchemaInfo();
// Initiate call back for schema construction
handler.startSchemaConstruction(firstProperty.getNS(), info.getPrefix());
handleAnnotation(info, 0);
XMPSchemaGenerator rngGenerator = new XMPSchemaGenerator(firstProperty.getNS(), info.getLabel(),
info.getDescription(), propInfoList);
return rngGenerator.getModel();
}
private void handleAnnotation(SchemaInfo schemaInfo, int index)
{
DAnnotation annot = grammar.getAnnotation();
if (annot == null)
return;
List elements = annot.getChildren();
if (elements == null || index >= elements.size())
return;
RNGAnnotation rngAnnot = AnnotationsFactory.createAnnotation(elements.get(index));
if (rngAnnot == null)
return;
if (rngAnnot instanceof RNGSchemaAnnotation)
{
((RNGSchemaAnnotation) rngAnnot).setAnnotationData(schemaInfo);
}
}
}
/**
* This class stores a {@link SchemaInfo} object and the list of {@link PropertyInfo} objects it contains
*
* @author hraghav
*/
class SchemaDataHolder
{
private ArrayList propList;
private SchemaInfo schemaInfo;
/**
*
* Constructs a new SchemaDataHolder.
*
* @param schemaInfo
* {@link SchemaInfo}
*/
SchemaDataHolder(SchemaInfo schemaInfo)
{
this.schemaInfo = schemaInfo;
propList = new ArrayList();
}
/**
* Adds a property to the list of properties
*
* @param propInfo
* {@link PropertyInfo} object to add to the list
*/
void addPropList(PropertyInfo propInfo)
{
if (propInfo != null)
this.propList.add(propInfo);
}
/**
* @return The {@link SchemaInfo} object contained in this object
*/
SchemaInfo getSchemaInfo()
{
return schemaInfo;
}
/**
* @return List of {@link PropertyInfo} objects contained in this object
*/
ArrayList getPropList()
{
return propList;
}
}