All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jena.schemagen Maven / Gradle / Ivy

Go to download

Jena is a Java framework for building Semantic Web applications. It provides a programmatic environment for RDF, RDFS and OWL, SPARQL and includes a rule-based inference engine.

The newest version!
/*****************************************************************************
 * Source code information
 * -----------------------
 * Original author    Ian Dickinson, HP Labs Bristol
 * Author email       [email protected]
 * Package            Jena 2
 * Web                http://sourceforge.net/projects/jena/
 * Created            14-Apr-2003
 * Filename           $RCSfile: schemagen.java,v $
 * Revision           $Revision: 1.13 $
 * Release status     $State: Exp $
 *
 * Last modified on   $Date: 2010/06/11 00:08:07 $
 *               by   $Author: ian_dickinson $
 *
 * (c) Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP
 * (see footer for full conditions)
 *****************************************************************************/

// Package
///////////////
package jena;


// Imports
///////////////
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.apache.xerces.util.XMLChar;
import org.slf4j.LoggerFactory;

import com.hp.hpl.jena.ontology.*;
import com.hp.hpl.jena.rdf.model.*;
import com.hp.hpl.jena.shared.JenaException;
import com.hp.hpl.jena.util.FileManager;
import com.hp.hpl.jena.util.iterator.*;
import com.hp.hpl.jena.vocabulary.*;



/**
 * 

* A vocabulary generator, that will consume an ontology or other vocabulary file, * and generate a Java file with the constants from the vocabulary compiled in. * Designed to be highly flexible and customisable. *

* * @author Ian Dickinson * (email) * @version CVS $Id: schemagen.java,v 1.13 2010/06/11 00:08:07 ian_dickinson Exp $ */ public class schemagen { // Constants ////////////////////////////////// /** The namespace for the configuration model is {@value} */ public static final String NS = "http://jena.hpl.hp.com/2003/04/schemagen#"; /** The default location of the configuration model is {@value} */ public static final String DEFAULT_CONFIG_URI = "file:schemagen.rdf"; /** The default marker string for denoting substitutions is {@value} */ public static final String DEFAULT_MARKER = "%"; /** Default template for writing out value declarations */ public static final String DEFAULT_TEMPLATE = "public static final %valclass% %valname% = m_model.%valcreator%( \"%valuri%\" );"; /** Default template for writing out individual declarations */ public static final String DEFAULT_INDIVIDUAL_TEMPLATE = "public static final %valclass% %valname% = m_model.%valcreator%( \"%valuri%\", %valtype% );"; /** Default template for writing out individual declarations for non-ontology vocabularies */ public static final String DEFAULT_RDFS_INDIVIDUAL_TEMPLATE = "public static final %valclass% %valname% = m_model.%valcreator%( \"%valuri%\" );"; /** Default template for the file header */ public static final String DEFAULT_HEADER_TEMPLATE = "/* CVS $" + "Id: $ */%nl%%package% %nl%%imports% %nl%/**%nl% * Vocabulary definitions from %sourceURI% %nl% * @author Auto-generated by schemagen on %date% %nl% */"; /** Default line length for comments before wrap */ public static final int COMMENT_LENGTH_LIMIT = 80; /** List of Java reserved keywords, see this list. */ public static final String[] JAVA_KEYWORDS = { "abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package", "synchronized", "boolean", "do", "if", "private", "this", "break", "double", "implements", "protected", "throw", "byte", "else", "import", "public", "throws", "case", "enum", "instanceof", "return", "transient", "catch", "extends", "int", "short", "try", "char", "final", "interface", "static", "void", "class", "finally", "long", "strictfp", "volatile", "const", "float", "native", "super", "while" }; // Static variables ////////////////////////////////// private static List KEYWORD_LIST; static { KEYWORD_LIST = Arrays.asList( JAVA_KEYWORDS ); } // Instance variables ////////////////////////////////// /** Schemagen options interface */ protected SchemagenOptions m_options; /** The model that contains the input source */ protected OntModel m_source; /** The output stream we write to */ protected PrintStream m_output; /** Option definitions */ /** Stack of replacements to apply */ protected List m_replacements = new ArrayList(); /** Output file newline char - default is Unix, override with --dos */ protected String m_nl = "\n"; /** Size of indent step */ protected int m_indentStep = 4; /** Set of names used so far */ protected Set m_usedNames = new HashSet(); /** Map from resources to java names */ protected Map m_resourcesToNames = new HashMap(); /** List of allowed namespace URI strings for admissible values */ protected List m_includeURI = new ArrayList(); // Constructors ////////////////////////////////// // External signature methods ////////////////////////////////// /* Main entry point. See Javadoc for details of the many command line arguments */ public static void main( String[] args ) { try { new schemagen().go( args ); } catch (SchemagenException e) { System.err.println( "Schemagen failed to run:" ); System.err.println( e.getMessage() ); if (e.getCause() != null) { System.err.println( "Caused by: " + e.getCause().getMessage() ); } System.exit( 1 ); } } // Internal implementation methods ////////////////////////////////// /** Read the configuration parameters and do setup */ protected void go( String[] args ) { go( new SchemagenOptionsImpl( args ) ); } /** Handle initial configuration options, then initiate processing */ protected void go( SchemagenOptions options ) { m_options = options; // check for user requesting help if (m_options.hasHelpOption()) { usage(); } // got the configuration, now we can begin processing processInput(); } /** The sequence of steps to process an entire file */ protected void processInput() { addIncludes(); determineLanguage(); selectInput(); selectOutput(); setGlobalReplacements(); processHeader(); writeClassDeclaration(); writeInitialDeclarations(); writeProperties(); writeClasses(); writeIndividuals(); writeClassClose(); processFooter(); closeOutput(); } /** Add the included files */ protected void addIncludes() { // add any extra uri's that are allowed in the filter m_includeURI.addAll( m_options.getIncludeOption() ); } /** Create the source model after determining which input language */ protected void determineLanguage() { OntModelSpec s = null; if (m_options.hasLangDamlOption()) { // DAML language specified if (m_options.hasUseInfOption()) { s = OntModelSpec.DAML_MEM_RULE_INF; } else { s = OntModelSpec.DAML_MEM; } } else if (m_options.hasLangRdfsOption()) { // RDFS language specified if (m_options.hasUseInfOption()) { s = OntModelSpec.RDFS_MEM_RDFS_INF; } else { s = OntModelSpec.RDFS_MEM; } } else { // owl is the default // s = OntModelSpec.getDefaultSpec( ProfileRegistry.OWL_LANG ); if (m_options.hasUseInfOption()) { s = OntModelSpec.OWL_MEM_RULE_INF; } else { s = OntModelSpec.OWL_MEM; } } m_source = ModelFactory.createOntologyModel( s, null ); m_source.getDocumentManager().setProcessImports( false ); // turn off strict checking on request if (m_options.hasNoStrictOption()) { m_source.setStrictMode( false ); } } /** Identify the URL that is to be read in and translated to a vocabulary file, and load the source into the source model */ protected void selectInput() { if (!m_options.hasInputOption()) { usage(); } String input = SchemagenUtils.urlCheck( m_options.getInputOption().getURI() ); String syntax = m_options.getEncodingOption(); try { FileManager.get().readModel( m_source, input, syntax ); } catch (JenaException e) { abort( "Failed to read input source " + input, e ); } } /** Identify the file we are to write the output to */ protected void selectOutput() { String outFile = m_options.getOutputOption(); if (outFile == null) { m_output = System.out; } else { try { // check for package name String packageName = m_options.getPackagenameOption(); if (packageName != null) { String packagePath = ""; // build the package path (e.g. com.foo.bar -> /com/foo/bar) for (String p: packageName.split( "\\." )) { packagePath = packagePath + File.separator + p; } if (!outFile.endsWith( packagePath )) { outFile = outFile + packagePath; } } File out = new File( outFile ); if (!out.exists() && !outFile.endsWith( ".java" )) { // create the directory if needed out.mkdirs(); } if (out.isDirectory()) { // create a file in this directory named classname.java String fileName = outFile + File.separator + getClassName() + ".java"; out = new File( fileName ); } m_output = new PrintStream( new FileOutputStream( out ) ); } catch (Exception e) { abort( "I/O error while trying to open file for writing: " + outFile, e ); } } // check for DOS line endings if (m_options.hasDosOption()) { m_nl = "\r\n"; } } /** Process the header at the start of the file, if defined */ protected void processHeader() { String header = m_options.hasHeaderOption() ? m_options.getHeaderOption() : DEFAULT_HEADER_TEMPLATE; // user can turn of header processing, default is to have it on if (!m_options.hasNoheaderOption()) { writeln( 0, substitute( header ) ); } else { // we have to do the imports at least writeln( 0, "import com.hp.hpl.jena.rdf.model.*;" ); if (m_options.hasOntologyOption()) { writeln( 0, "import com.hp.hpl.jena.ontology.*;" ); } if (m_options.hasIncludeSourceOption()) { writeln( 0, "import java.io.ByteArrayInputStream;" ); } } } /** Process the footer at the end of the file, if defined */ protected void processFooter() { String footer = m_options.getFooterOption(); if (footer != null) { writeln( 0, substitute( footer ) ); } } /** The list of replacements that are always available */ protected void setGlobalReplacements() { addReplacementPattern( "date", new SimpleDateFormat( "dd MMM yyyy HH:mm").format( new Date() ) ); addReplacementPattern( "package", m_options.hasPackagenameOption() ? ("package " + m_options.getPackagenameOption() + ";") : "" ); addReplacementPattern( "imports", getImports() ); addReplacementPattern( "classname", getClassName() ); addReplacementPattern( "nl", m_nl ); // protect \ in Windows file pathnames // looks for file:.* or C:.* (or variants thereof) String source = m_options.getInputOption().getURI(); if (source.matches( "(file:|[A-Za-z]:).*$" )) { source = source.replace( "\\", "\\\\" ); } addReplacementPattern( "sourceURI", source ); } /** Add a pattern-value pair to the list of available patterns */ protected void addReplacementPattern( String key, String replacement ) { if (replacement != null && key != null) { String marker = m_options.getMarkerOption(); marker = (marker == null) ? DEFAULT_MARKER : marker; try { m_replacements.add( new Replacement( Pattern.compile( marker + key + marker ), replacement ) ); } catch (PatternSyntaxException e) { abort( "Malformed regexp pattern " + marker + key + marker, e ); } } } /** Pop n replacements off the stack */ protected void pop( int n ) { for (int i = 0; i < n; i++) { m_replacements.remove( m_replacements.size() - 1 ); } } /** Close the output file */ protected void closeOutput() { m_output.flush(); m_output.close(); } /** Abort due to exception */ protected void abort( String msg, Exception cause ) { throw new SchemagenException( msg, cause ); } /** Print usage message and abort */ protected void usage() { System.err.println( "Usage:" ); System.err.println( " java jena.schemagen [options ...]" ); System.err.println(); System.err.println( "Commonly used options include:" ); System.err.println( " -i the source document as a file or URL." ); System.err.println( " -n the name of the created Java class." ); System.err.println( " -a the namespace URI of the source document." ); System.err.println( " -o the file to write the generated class into." ); System.err.println( " -o
the directory in which the generated Java class is created." ); System.err.println( " By default, output goes to stdout." ); System.err.println( " -e the encoding of the input document (N3, RDF/XML, etc)." ); System.err.println( " -c a filename or URL for an RDF document containing " ); System.err.println( " configuration parameters." ); System.err.println(); System.err.println( "Many other options are available. See the schemagen HOWTO in the " ); System.err.println( "Jena documentation for full details." ); System.exit( 1 ); } /** Use the current replacements list to do the subs in the given string */ protected String substitute( String sIn ) { String s = sIn; for (Iterator i = m_replacements.iterator(); i.hasNext(); ) { Replacement r = i.next(); s = r.pattern.matcher( s ).replaceAll( r.sub ); } return s; } /** Add the appropriate indent to a buffer */ protected int indentTo( int i, StringBuffer buf ) { int indent = i * m_indentStep; for (int j = 0; j < indent; j++) { buf.append( ' ' ); } return indent; } /** Write a blank line, with indent and newline */ protected void writeln( int indent ) { writeln( indent, "" ); } /** Write out the given string with n spaces of indent, with newline */ protected void writeln( int indent, String s ) { write( indent, s ); m_output.print( m_nl ); } /** Write out the given string with n spaces of indent */ protected void write( int indentLevel, String s ) { for (int i = 0; i < (m_indentStep * indentLevel); i++) { m_output.print( " " ); } m_output.print( s ); } /** Determine the list of imports to include in the file */ protected String getImports() { StringBuffer buf = new StringBuffer(); buf.append( "import com.hp.hpl.jena.rdf.model.*;" ); buf.append( m_nl ); if (useOntology()) { buf.append( "import com.hp.hpl.jena.ontology.*;" ); buf.append( m_nl ); } if (includeSource()) { buf.append( "import java.io.ByteArrayInputStream;" ); buf.append( m_nl ); } return buf.toString(); } /** Determine the class name of the vocabulary from the URI */ protected String getClassName() { // if a class name is given, just use that if (m_options.hasClassnameOption()) { return m_options.getClassnameOption(); } // otherwise, we generate a name based on the URI String uri = m_options.getInputOption().getURI(); // remove any suffixes uri = (uri.endsWith( "#" )) ? uri.substring( 0, uri.length() - 1 ) : uri; uri = (uri.endsWith( ".daml" )) ? uri.substring( 0, uri.length() - 5 ) : uri; uri = (uri.endsWith( ".owl" )) ? uri.substring( 0, uri.length() - 4 ) : uri; uri = (uri.endsWith( ".rdf" )) ? uri.substring( 0, uri.length() - 4 ) : uri; uri = (uri.endsWith( ".rdfs" )) ? uri.substring( 0, uri.length() - 5 ) : uri; uri = (uri.endsWith( ".n3" )) ? uri.substring( 0, uri.length() - 3 ) : uri; uri = (uri.endsWith( ".xml" )) ? uri.substring( 0, uri.length() - 4 ) : uri; uri = (uri.endsWith( ".ttl" )) ? uri.substring( 0, uri.length() - 4 ) : uri; // now work back to the first non name character from the end int i = uri.length() - 1; for (; i > 0; i--) { if (!Character.isUnicodeIdentifierPart( uri.charAt( i ) ) && uri.charAt( i ) != '-') { i++; break; } } String name = uri.substring( i ); // optionally add name suffix if (m_options.hasClassnameSuffixOption()) { name = name + m_options.getClassnameSuffixOption(); } // now we make the name into a legal Java identifier return asLegalJavaID( name, true ); } /** Answer true if we are using ontology terms in this vocabulary */ protected boolean useOntology() { return m_options.hasOntologyOption(); } /** Answer true if all comments are suppressed */ protected boolean noComments() { return m_options.hasNoCommentsOption(); } /** Answer true if ontology source code is to be included */ protected boolean includeSource() { return m_options.hasIncludeSourceOption(); } /** Convert s to a legal Java identifier; capitalise first char if cap is true */ protected String asLegalJavaID( String s, boolean cap ) { StringBuffer buf = new StringBuffer(); int i = 0; // treat the first character specially - must be able to start a Java ID, may have to up-case try { for (; !Character.isJavaIdentifierStart( s.charAt( i )); i++) { /**/ } } catch (StringIndexOutOfBoundsException e) { System.err.println( "Could not identify legal Java identifier start character in '" + s + "', replacing with __" ); return "__"; } buf.append( cap ? Character.toUpperCase( s.charAt( i ) ) : s.charAt( i ) ); // copy the remaining characters - replace non-legal chars with '_' for (++i; i < s.length(); i++) { char c = s.charAt( i ); buf.append( Character.isJavaIdentifierPart( c ) ? c : '_' ); } // check for illegal keyword if (KEYWORD_LIST.contains( buf.toString() )) { buf.append( '_' ); } return buf.toString(); } /** The opening class declaration */ protected void writeClassDeclaration() { write( 0, "public class " ); write( 0, getClassName() ); write( 0, " " ); if (m_options.hasClassdecOption()) { write( 0, m_options.getClassdecOption() ); } writeln( 0, "{" ); } /** The close of the class decoration */ protected void writeClassClose() { writeln( 0, "}" ); } /** Write the declarations at the head of the class */ protected void writeInitialDeclarations() { writeModelDeclaration(); writeSource(); writeNamespace(); if (m_options.hasDeclarationsOption()) { writeln( 0, m_options.getDeclarationsOption() ); } } /** Write the declaration of the model */ protected void writeModelDeclaration() { if (useOntology()) { String lang = "OWL"; if (m_options.hasLangDamlOption()) { lang = "DAML"; } else if (m_options.hasLangRdfsOption()) { lang = "RDFS"; } writeln( 1, "/**

The ontology model that holds the vocabulary terms

*/" ); writeln( 1, "private static OntModel m_model = ModelFactory.createOntologyModel( OntModelSpec." + lang + "_MEM, null );" ); } else { writeln( 1, "/**

The RDF model that holds the vocabulary terms

*/" ); writeln( 1, "private static Model m_model = ModelFactory.createDefaultModel();" ); } writeln( 1 ); } /** Write the source code of the input model into the file itself */ protected void writeSource() { if (includeSource()) { // first save a copy of the source in compact form into a buffer ByteArrayOutputStream bos = new ByteArrayOutputStream(); m_source.write( bos, "N3" ); String output = bos.toString(); // now we embed each line of the source in the output writeln( 1, "private static final String SOURCE = " ); boolean first = true; StringTokenizer st = new StringTokenizer( output, "\n" ); while (st.hasMoreTokens()) { String tok = st.nextToken(); if (tok.endsWith( "\r" )) { tok = tok.substring( 0, tok.length() - 1 ); } write( 2, first ? " " : " + " ); write( 0, "\"" ); write( 0, protectQuotes( tok ) ); writeln( 2, "\\n\"" ); first = false; } // then we reference the string constant when reading the source // note that we avoid StringReader due to charset encoding issues writeln( 1, ";" ); writeln( 0, "" ); writeln( 1, "/** Read the ontology definition into the source model */ " ); writeln( 1, "static { " ); writeln( 2, "m_model.read( new ByteArrayInputStream( SOURCE.getBytes() ), null, \"N3\" );" ); writeln( 1, "}" ); writeln( 0, "" ); } } /** Protect any double quotes in the given string so that it's a legal Java String */ private String protectQuotes( String s ) { int nDquote = 0; for (int i = 0; i < s.length(); i++ ) { if (s.charAt( i ) == '"' ) { nDquote++; } } if (nDquote == 2) { // need to protect the begin and end quote chars return s.replaceAll( "\"", "\\\\\"" ); } else if (nDquote > 2) { // embedded quote chars in the string // N3 convention is to use triple-quote blocks int qStart = s.indexOf( '"' ); int qEnd = s.lastIndexOf( '"' ); StringBuffer s0 = new StringBuffer( s.length() ); for (int i = 0; i < s.length(); i++ ) { char c = s.charAt( i ); if (c == '"' ) { // protect embedded " characters, treating the outer pair differently // than any inner quotes if (i == qStart || i == qEnd) { s0.append( "\\\"\\\"\\\"" ); } else { s0.append( "\\\"" ); } } else if (c == '\\' ) { // protect embedded \ characters s0.append( "\\\\" ); } else { s0.append( c ); } } return s0.toString(); } else { return s; } } /** Write the string and resource that represent the namespace */ protected void writeNamespace() { String nsURI = determineNamespaceURI(); writeln( 1, "/**

The namespace of the vocabulary as a string

*/" ); writeln( 1, "public static final String NS = \"" + nsURI + "\";" ); writeln( 1 ); writeln( 1, "/**

The namespace of the vocabulary as a string

" ); writeln( 1, " * @see #NS */" ); writeln( 1, "public static String getURI() {return NS;}" ); writeln( 1 ); writeln( 1, "/**

The namespace of the vocabulary as a resource

*/" ); writeln( 1, "public static final Resource NAMESPACE = m_model.createResource( NS );" ); writeln( 1 ); } /** Determine what the namespace URI for this vocabulary is */ protected String determineNamespaceURI() { // we have a sequence of strategies for determining the ontology namespace String ns = getOptionNamespace(); if (ns == null) { ns = getDefaultPrefixNamespace(); } if (ns == null) { ns = getOntologyElementNamespace(); } if (ns == null) { ns = guessNamespace(); } // did we get one? if (ns == null) { abort( "Could not determine the base URI for the input vocabulary", null ); } m_includeURI.add( ns ); return ns; } /** User has set namespace via a schemagen option */ protected String getOptionNamespace() { return m_options.hasNamespaceOption() ? m_options.getNamespaceOption().getURI() : null; } /** Document has set an empty prefix for the model */ protected String getDefaultPrefixNamespace() { // alternatively, the default namespace may be set in the prefix mapping read from the input document String defaultNS = m_source.getNsPrefixURI( "" ); if (defaultNS == null) { defaultNS = m_source.getBaseModel().getNsPrefixURI( "" ); } return defaultNS; } /** Document has an owl:Ontology or daml:Ontology element */ protected String getOntologyElementNamespace() { // if we are using an ontology model, we can get the namespace URI from the ontology element String uri = null; StmtIterator i = m_source.getBaseModel() .listStatements( null, RDF.type, m_source.getProfile().ONTOLOGY() ); if (i.hasNext()) { Resource ont = i.nextStatement().getSubject(); uri = ont.getURI(); // ensure ends with namespace separator char char ch = uri.charAt( uri.length() - 1 ); boolean endsWithNCNameCh = XMLChar.isNCName( ch ); uri = endsWithNCNameCh ? uri + "#" : uri; // check for ambiguous answers if (i.hasNext()) { System.err.println( "Warning: ambiguous default namespace - there is more than one owl:Ontology element." ); System.err.println( "Picking first choice: " + uri + ". Other choices are:" ); while (i.hasNext()) { System.err.print( " " ); System.err.print( i.nextStatement().getString() ); } System.err.println(); System.err.println( "Use the -a option to specify a particular namespace if required." ); } } return uri; } /** Guess the URI from the most prevalent URI */ protected String guessNamespace() { Map nsCount = new HashMap(); // count all of the namespaces used in the model for (StmtIterator i = m_source.listStatements(); i.hasNext(); ) { Statement s = i.next(); countNamespace( s.getSubject(), nsCount ); countNamespace( s.getPredicate(), nsCount ); if (s.getObject().isResource()) { countNamespace( s.getResource(), nsCount ); } } // now find the maximal element String ns = null; int max = 0; for (Iterator i = nsCount.keySet().iterator(); i.hasNext(); ) { String nsKey = i.next(); // we ignore the usual suspects if (! (OWL.getURI().equals( nsKey ) || RDF.getURI().equals( nsKey ) || RDFS.getURI().equals( nsKey ) || XSD.getURI().equals( nsKey ))) { // not an ignorable namespace int count = nsCount.get( nsKey ).intValue(); if (count > max) { // highest count seen so far max = count; ns = nsKey; } } } return ns; } /** Record a use of the given namespace in the count map */ private void countNamespace( Resource r, Map nsCount ) { if (!r.isAnon()) { String ns = r.getNameSpace(); // increment the count for this namespace Integer count = nsCount.containsKey( ns ) ? (Integer) nsCount.get( ns ) : new Integer( 0 ); Integer count1 = new Integer( count.intValue() + 1 ); nsCount.put( ns, count1 ); } } /** Write the list of properties */ protected void writeProperties() { if (m_options.hasNopropertiesOption()) { return; } if (m_options.hasPropertySectionOption()) { writeln( 0, m_options.getPropertySectionOption()); } if (useOntology()) { writeObjectProperties(); writeDatatypeProperties(); writeAnnotationProperties(); // we also write out the RDF properties, to mop up any props that are not stated as // object, datatype or annotation properties writeRDFProperties( true ); } else { writeRDFProperties( false ); } } /** Write any object properties in the vocabulary */ protected void writeObjectProperties() { String template = m_options.hasPropTemplateOption() ? m_options.getPropTemplateOption() : DEFAULT_TEMPLATE; if (!m_options.hasLangRdfsOption()) { for (Iterator i = sorted( m_source.listObjectProperties() ); i.hasNext(); ) { writeValue( (Resource) i.next(), template, "ObjectProperty", "createObjectProperty", "_PROP" ); } } } /** Write any datatype properties in the vocabulary */ protected void writeDatatypeProperties() { String template = m_options.hasPropTemplateOption() ? m_options.getPropTemplateOption() : DEFAULT_TEMPLATE; if (!m_options.hasLangRdfsOption()) { for (Iterator i = sorted( m_source.listDatatypeProperties() ); i.hasNext(); ) { writeValue( (Resource) i.next(), template, "DatatypeProperty", "createDatatypeProperty", "_PROP" ); } } } /** Write any annotation properties in the vocabulary */ protected void writeAnnotationProperties() { String template = m_options.hasPropTemplateOption() ? m_options.getPropTemplateOption() : DEFAULT_TEMPLATE; if (!m_options.hasLangRdfsOption()) { for (Iterator i = sorted( m_source.listAnnotationProperties() ); i.hasNext(); ) { writeValue( (Resource) i.next(), template, "AnnotationProperty", "createAnnotationProperty", "_PROP" ); } } } /** Write any vanilla RDF properties in the vocabulary */ protected void writeRDFProperties( boolean useOntProperty ) { String template = m_options.hasPropTemplateOption() ? m_options.getPropTemplateOption() : DEFAULT_TEMPLATE; String propType = useOntProperty ? "OntProperty" : "Property"; // select the appropriate properties based on the language choice Resource[] props; if (m_options.hasLangOwlOption()) { props = new Resource[] {OWL.ObjectProperty, OWL.DatatypeProperty, RDF.Property}; } else if (m_options.hasLangDamlOption()) { props = new Resource[] {DAML_OIL.ObjectProperty, DAML_OIL.DatatypeProperty, RDF.Property}; } else { props = new Resource[] {RDF.Property}; } // collect the properties to be written List propertyResources = new ArrayList(); for (int j = 0; j < props.length; j++) { for (StmtIterator i = m_source.listStatements( null, RDF.type, props[j] ); i.hasNext(); ) { propertyResources.add( i.nextStatement().getSubject() ); } } // now write the properties for (Iterator i = sorted( propertyResources ); i.hasNext(); ) { writeValue( (Resource) i.next(), template, propType, "create" + propType, "_PROP" ); } } /** Write any classes in the vocabulary */ protected void writeClasses() { if (m_options.hasNoclassesOption()) { return; } if (m_options.hasClassSectionOption()) { writeln( 0, m_options.getClassSectionOption()); } if (useOntology()) { writeOntClasses(); } else { writeRDFClasses(); } } /** Write classes as ontology terms */ protected void writeOntClasses() { String template = m_options.hasClassTemplateOption() ? m_options.getClassTemplateOption() : DEFAULT_TEMPLATE; for (Iterator i = sorted( m_source.listClasses() ); i.hasNext(); ) { writeValue( (Resource) i.next(), template, "OntClass", "createClass", "_CLASS" ); } } /** Write classes as vanilla RDF terms */ protected void writeRDFClasses() { String template = m_options.hasClassTemplateOption() ? m_options.getClassTemplateOption() : DEFAULT_TEMPLATE; // make sure we're looking for the appropriate type of class Resource cls = OWL.Class; if (m_options.hasLangDamlOption()) { cls = DAML_OIL.Class; } else if (m_options.hasLangRdfsOption()) { cls = RDFS.Class; } // collect the classes to list List classes = m_source.listStatements( null, RDF.type, cls ).mapWith( new Map1() { public Resource map1( Statement s ) { return s.getSubject(); }} ).toList(); for (Iterator i = sorted( classes ); i.hasNext(); ) { writeValue( (Resource) i.next(), template, "Resource", "createResource", "_CLASS" ); } } /** Write any instances (individuals) in the vocabulary */ protected void writeIndividuals() { if (m_options.hasNoindividualsOption()) { return; } if (m_options.hasIndividualsSectionOption()) { writeln( 0, m_options.getIndividualsSectionOption() ); } if (useOntology()) { writeOntIndividuals(); } else { writeRDFIndividuals(); } } /** Write individuals as ontology terms */ protected void writeOntIndividuals() { String template = m_options.hasIndividualTemplateOption() ? m_options.getIndividualTemplateOption() : DEFAULT_INDIVIDUAL_TEMPLATE; for (Iterator i = selectIndividuals(); i.hasNext(); ) { Individual ind = ((Resource) i.next()).as( Individual.class ); // do we have a local class resource Resource cls = ind.getOntClass(); if (cls == null) { cls = OWL.Thing; } String varName = m_resourcesToNames.get( cls ); String valType = (varName != null) ? varName : "m_model.createClass( \"" + cls.getURI() + "\" )"; // push the individuals type onto the stack addReplacementPattern( "valtype", valType ); writeValue( ind, template, "Individual", "createIndividual", "_INSTANCE" ); pop( 1 ); } } /** Write individuals as vanilla RDF terms */ protected void writeRDFIndividuals() { String template = m_options.hasIndividualTemplateOption() ? m_options.getIndividualTemplateOption() : DEFAULT_RDFS_INDIVIDUAL_TEMPLATE; for (Iterator i = selectIndividuals(); i.hasNext(); ) { writeValue( (Resource) i.next(), template, "Resource", "createResource", "_INSTANCE" ); } } /** Answer an iterator over the individuals selected for output */ protected ExtendedIterator selectIndividuals() { List candidates = new ArrayList(); for (StmtIterator i = m_source.listStatements( null, RDF.type, (RDFNode) null ); i.hasNext(); ) { Statement candidate = i.nextStatement(); if (candidate.getObject().isResource()) { Resource candObj = candidate.getResource(); Resource candSubj = candidate.getSubject(); // ignore RDFS and OWL builtins if (!candObj.isAnon()) { String candTypeURI = candObj.getURI(); if (candTypeURI.startsWith( RDF.getURI() ) || candTypeURI.startsWith( OWL.getURI() ) || candTypeURI.startsWith( RDFS.getURI() )) { continue; } } // note that whether candSubj is included is tested later on by {@link #filter} if (!candSubj.isAnon() && (isIncluded( candObj ) || isIncluded( candSubj )) && !candidates.contains( candSubj )) { candidates.add( candSubj ); } } } return sorted( candidates ); } /** * Answer true if the given resource is accepted for presentation in the output, which * is true iff it is a URI node, whose namespace is one of the accepted namespaces in * {@link #m_includeURI}. * @param r A resource to test * @return True if the resource is to be included in the generated output */ protected boolean isIncluded( Resource r ) { boolean accepted = false; if (!r.isAnon()) { String uri = r.getURI(); for (Iterator j = m_includeURI.iterator(); !accepted && j.hasNext(); ) { accepted = uri.startsWith( j.next() ); } } return accepted; } /** Write the value declaration out using the given template, optionally creating comments */ protected void writeValue( Resource r, String template, String valueClass, String creator, String disambiguator ) { if (!filter( r )) { if (!noComments() && hasComment( r )) { writeln( 1, formatComment( getComment( r ) ) ); } // push the local bindings for the substitution onto the stack addReplacementPattern( "valuri", r.getURI() ); addReplacementPattern( "valname", getValueName( r, disambiguator )); addReplacementPattern( "valclass", valueClass ); addReplacementPattern( "valcreator", creator ); // write out the value writeln( 1, substitute( template ) ); writeln( 1 ); // pop the local replacements off the stack pop( 4 ); } } /** Answer true if the given resource has an rdf:comment or daml:comment */ protected boolean hasComment( Resource r ) { return r.hasProperty( RDFS.comment ) || r.hasProperty( DAML_OIL.comment ); } /** Answer all of the commentary on the given resource, as a string */ protected String getComment( Resource r ) { StringBuffer comment = new StringBuffer(); // collect any RDFS or DAML comments attached to the node for (NodeIterator ni = m_source.listObjectsOfProperty( r, RDFS.comment ); ni.hasNext(); ) { RDFNode n = ni.nextNode(); if (n instanceof Literal) { comment.append( ((Literal) n).getLexicalForm().trim() ); } else { LoggerFactory.getLogger( getClass() ).debug( "Not a literal: " + n ); } } for (NodeIterator ni = m_source.listObjectsOfProperty( r, DAML_OIL.comment ); ni.hasNext(); ) { comment.append( ((Literal) ni.nextNode()).getLexicalForm().trim() ); } return comment.toString(); } /** Format the comment as Javadoc, and limit the line width */ protected String formatComment( String comment ) { StringBuffer buf = new StringBuffer(); buf.append( "/**

" ); boolean inSpace = false; int pos = buf.length(); boolean singleLine = true; // now format the comment by compacting whitespace and limiting the line length // add the prefix to the start of each line for (int i = 0; i < comment.length(); i++ ) { char c = comment.charAt( i ); // compress whitespace if (Character.isWhitespace( c )) { if (inSpace) { continue; // more than one space is ignored } else { c = ' '; // map all whitespace to 0x20 inSpace = true; } } else { inSpace = false; } // escapes? if (c == '\\') { c = comment.charAt( ++i ); switch (c) { case 'n': buf.append( m_nl ); pos = indentTo( 1, buf ); buf.append( " * " ); pos += 3; singleLine = false; break; default: // add other escape sequences above break; } } else if (c == '<') { buf.append( "<" ); pos += 4; } else if (c == '>') { buf.append( ">" ); pos += 4; } else if (c == '&') { buf.append( "&" ); pos += 5; } else { // add the char buf.append( c ); pos++; } // wrap any very long lines at 120 chars if ((pos > COMMENT_LENGTH_LIMIT) && (inSpace)) { buf.append( m_nl ); pos = indentTo( 1, buf ); buf.append( " * " ); pos += 3; singleLine = false; } } buf.append( "

" ); buf.append( singleLine ? "" : m_nl ); indentTo( singleLine ? 0 : 1, buf ); buf.append( " */" ); return buf.toString(); } /** Answer true if resource r does not show in output */ protected boolean filter( Resource r ) { if (r.isAnon()) { return true; } // if we've already processed this resource once, ignore it next time if (m_resourcesToNames.containsKey( r )) { return true; } // search the allowed URI's for (Iterator i = m_includeURI.iterator(); i.hasNext(); ) { String uri = i.next(); if (r.getURI().startsWith( uri )) { // in return false; } } // we allow individuals whose class is not in the included NS's, unless opt strict-individuals is true */ if (!m_options.hasStrictIndividualsOption()) { for (StmtIterator j = r.listProperties( RDF.type ); j.hasNext(); ) { // we search the rdf:types of this resource Resource typeRes = j.nextStatement().getResource(); if (!typeRes.isAnon()) { String typeURI = typeRes.getURI(); // for any type that is in a permitted NS for (Iterator i = m_includeURI.iterator(); i.hasNext(); ) { String uri = i.next(); if (typeURI.startsWith( uri )) { // in return false; } } } } } // default is out return true; } /** Answer the Java value name for the URI */ protected String getValueName( Resource r, String disambiguator ) { // the id name is basically the local name of the resource, possibly in upper case String name = m_options.hasUcNamesOption() ? getUCValueName( r ) : r.getLocalName(); // must be legal java name = asLegalJavaID( name, false ); // must not clash with an existing name int attempt = 0; String baseName = name; while (m_usedNames.contains( name )) { name = (attempt == 0) ? (name + disambiguator) : (baseName + disambiguator + attempt); attempt++; } // record this name so that we don't use it again (which will stop the vocabulary from compiling) m_usedNames.add( name ); // record the mapping from resource to name m_resourcesToNames.put( r, name ); return name; } /** Answer the local name of resource r mapped to upper case */ protected String getUCValueName( Resource r ) { StringBuffer buf = new StringBuffer(); String localName = r.getLocalName(); char lastChar = 0; for (int i = 0; i < localName.length(); i++) { char c = localName.charAt(i); if (Character.isLowerCase(lastChar) && Character.isUpperCase(c)) { buf.append( '_' ); } buf.append( Character.toUpperCase(c) ); lastChar = c; } return buf.toString(); } /** Answer an iterator that contains the elements of the given list, but sorted by URI */ protected ExtendedIterator sorted( ExtendedIterator i ) { return sorted( i.toList() ); } /** Answer an iterator that contains the elements of the given iterator, but sorted by URI */ protected ExtendedIterator sorted( List members ) { Collections.sort( members, new Comparator() { public int compare( RDFNode n0, RDFNode n1 ) { if (n0.isLiteral() || n1.isLiteral()) { if (n0.isLiteral() && n1.isLiteral()) { // two literals Literal l0 = (Literal) n0; Literal l1 = (Literal) n1; return l0.getLexicalForm().compareTo( l1.getLexicalForm() ); } else { return n0.isLiteral() ? -1 : 1; } } else { Resource r0 = (Resource) n0; Resource r1 = (Resource) n1; if (r0.isAnon() && r1.isAnon()) { // two anonID's - the order is important as long as its consistent return r0.getId().toString().compareTo( r1.getId().toString() ); } else if (r0.isAnon()) { return -1; } else if (r1.isAnon()) { return 1; } else { // two named resources return r0.getURI().compareTo( r1.getURI() ); } } }} ); return WrappedIterator.create( members.iterator() ); } //============================================================================== // Inner class definitions //============================================================================== public interface SchemagenOptions { /* Constants for the various options we can set */ public enum OPT { /** Select an alternative config file; use -c <filename> on command line */ CONFIG_FILE, /** Turn off all comment output; use --nocomments on command line; use sgen:noComments in config file */ NO_COMMENTS, /** Nominate the URL of the input document; use -i <URL> on command line; use sgen:input in config file */ INPUT, /** Specify that the language of the source is DAML+OIL; use --daml on command line; use sgen:daml in config file */ LANG_DAML, /** Specify that the language of the source is OWL (the default); use --owl on command line; use sgen:owl in config file */ LANG_OWL, /** Specify that the language of the source is RDFS; use --rdfs on command line; use sgen:rdfs in config file */ LANG_RDFS, /** Specify that destination file; use -o <fileName> on command line; use sgen:output in config file */ OUTPUT, /** Specify the file header; use --header "..." on command line; use sgen:header in config file */ HEADER, /** Specify the file footer; use --footer "..." on command line; use sgen:footer in config file */ FOOTER, /** Specify the uri of the configuration root node; use --root <URL> on command line */ ROOT, /** Specify the marker string for substitutions, default is '%'; use -m "..." on command line; use sgen:marker in config file */ MARKER, /** Specify the packagename; use --package <packagename> on command line; use sgen:package in config file */ PACKAGENAME, /** Use ontology terms in preference to vanilla RDF; use --ontology on command line; use sgen:ontology in config file */ ONTOLOGY, /** The name of the generated class; use -n <classname> on command line; use sgen:classname in config file */ CLASSNAME, /** Additional decoration for class header (such as implements); use --classdec <classname> on command line; use sgen:classdec in config file */ CLASSDEC, /** The namespace URI for the vocabulary; use -a <uri> on command line; use sgen:namespace in config file */ NAMESPACE, /** Additional declarations to add at the top of the class; use --declarations <...> on command line; use sgen:declarations in config file */ DECLARATIONS, /** Section declaration for properties section; use --propSection <...> on command line; use sgen:propSection in config file */ PROPERTY_SECTION, /** Section declaration for class section; use --classSection <...> on command line; use sgen:classSection in config file */ CLASS_SECTION, /** Section declaration for individuals section; use --individualsSection <...> on command line; use sgen:individualsSection in config file */ INDIVIDUALS_SECTION, /** Option to suppress properties in vocab file; use --noproperties <...> on command line; use sgen:noproperties in config file */ NOPROPERTIES, /** Option to suppress classes in vocab file; use --noclasses <...> on command line; use sgen:noclasses in config file */ NOCLASSES, /** Option to suppress individuals in vocab file; use --noindividuals <...> on command line; use sgen:noindividuals in config file */ NOINDIVIDUALS, /** Option for no file header; use --noheader <...> on command line; use sgen:noheader in config file */ NOHEADER, /** Template for writing out property declarations; use --propTemplate <...> on command line; use sgen:propTemplate in config file */ PROP_TEMPLATE, /** Template for writing out class declarations; use --classTemplate <...> on command line; use sgen:classTemplate in config file */ CLASS_TEMPLATE, /** Template for writing out individual declarations; use --individualTemplate <...> on command line; use sgen:individualTemplate in config file */ INDIVIDUAL_TEMPLATE, /** Option for mapping constant names to uppercase; use --uppercase <...> on command line; use sgen:uppercase in config file */ UC_NAMES, /** Option for including non-local URI's in vocabulary; use --include <uri> on command line; use sgen:include in config file */ INCLUDE, /** Option for adding a suffix to the generated class name; use --classnamesuffix <uri> on command line; use sgen:classnamesuffix in config file */ CLASSNAME_SUFFIX, /** Option for the presentation syntax (encoding) of the file; use -e encoding on command line; use sgen:encoding in config file */ ENCODING, /** Option to show the usage message; use --help on command line */ HELP, /** Option to generate an output file with DOS (\r\n) line endings. Default is Unix line endings. */ DOS, /** Option to generate to force the model to perform inference, off by default. */ USE_INF, /** Option to exclude instances of classes in the allowed namespaces, where the individuals themselves are in other namespaces; use --strictIndividuals on command line; use sgen:strictIndividuals in config file */ STRICT_INDIVIDUALS, /** Option to include the ontology source code in the generated file */ INCLUDE_SOURCE, /** Option to turn off strict checking in .a() */ NO_STRICT } public static final Object[][] m_optionDefinitions = new Object[][] { {OPT.CONFIG_FILE, new OptionDefinition( "-c", "configFile" ) }, {OPT.ROOT, new OptionDefinition( "-r", "root" ) }, {OPT.NO_COMMENTS, new OptionDefinition( "--nocomments", "noComments" ) }, {OPT.INPUT, new OptionDefinition( "-i", "input" ) }, {OPT.LANG_DAML, new OptionDefinition( "--daml", "daml" ) }, {OPT.LANG_OWL, new OptionDefinition( "--owl", "owl" ) }, {OPT.LANG_RDFS, new OptionDefinition( "--rdfs", "rdfs" ) }, {OPT.OUTPUT, new OptionDefinition( "-o", "output" ) }, {OPT.HEADER, new OptionDefinition( "--header", "header" ) }, {OPT.FOOTER, new OptionDefinition( "--footer", "footer" ) }, {OPT.MARKER, new OptionDefinition( "--marker", "marker" ) }, {OPT.PACKAGENAME, new OptionDefinition( "--package", "package" ) }, {OPT.ONTOLOGY, new OptionDefinition( "--ontology", "ontology" ) }, {OPT.CLASSNAME, new OptionDefinition( "-n", "classname" ) }, {OPT.CLASSDEC, new OptionDefinition( "--classdec", "classdec" ) }, {OPT.NAMESPACE, new OptionDefinition( "-a", "namespace" ) }, {OPT.DECLARATIONS, new OptionDefinition( "--declarations", "declarations" ) }, {OPT.PROPERTY_SECTION, new OptionDefinition( "--propSection", "propSection" ) }, {OPT.CLASS_SECTION, new OptionDefinition( "--classSection", "classSection" ) }, {OPT.INDIVIDUALS_SECTION, new OptionDefinition( "--individualsSection", "individualsSection" ) }, {OPT.NOPROPERTIES, new OptionDefinition( "--noproperties", "noproperties" ) }, {OPT.NOCLASSES, new OptionDefinition( "--noclasses", "noclasses" ) }, {OPT.NOINDIVIDUALS, new OptionDefinition( "--noindividuals", "noindividuals" ) }, {OPT.PROP_TEMPLATE, new OptionDefinition( "--propTemplate", "propTemplate" ) }, {OPT.CLASS_TEMPLATE, new OptionDefinition( "--classTemplate", "classTemplate" ) }, {OPT.INDIVIDUAL_TEMPLATE, new OptionDefinition( "--individualTemplate", "individualTemplate" ) }, {OPT.UC_NAMES, new OptionDefinition( "--uppercase", "uppercase" ) }, {OPT.INCLUDE, new OptionDefinition( "--include", "include" ) }, {OPT.CLASSNAME_SUFFIX, new OptionDefinition( "--classnamesuffix", "classnamesuffix" )}, {OPT.NOHEADER, new OptionDefinition( "--noheader", "noheader" )}, {OPT.ENCODING, new OptionDefinition( "-e", "encoding" )}, {OPT.HELP, new OptionDefinition( "--help", "help" )}, {OPT.DOS, new OptionDefinition( "--dos", "dos" )}, {OPT.USE_INF, new OptionDefinition( "--inference", "inference" )}, {OPT.STRICT_INDIVIDUALS, new OptionDefinition( "--strictIndividuals", "strictIndividuals" )}, {OPT.INCLUDE_SOURCE, new OptionDefinition( "--includeSource", "includeSource" )}, {OPT.NO_STRICT, new OptionDefinition( "--nostrict", "noStrict")}, }; public boolean hasConfigFileOption(); public String getConfigFileOption(); public boolean hasRootOption(); public String getRootOption(); public boolean hasNoCommentsOption(); public String getNoCommentsOption(); public boolean hasInputOption(); public Resource getInputOption(); public boolean hasLangDamlOption(); public String getLangDamlOption(); public boolean hasLangOwlOption(); public String getLangOwlOption(); public boolean hasLangRdfsOption(); public String getLangRdfsOption(); public boolean hasOutputOption(); public String getOutputOption(); public boolean hasHeaderOption(); public String getHeaderOption(); public boolean hasFooterOption(); public String getFooterOption(); public boolean hasMarkerOption(); public String getMarkerOption(); public boolean hasPackagenameOption(); public String getPackagenameOption(); public boolean hasOntologyOption(); public String getOntologyOption(); public boolean hasClassnameOption(); public String getClassnameOption(); public boolean hasClassdecOption(); public String getClassdecOption(); public boolean hasNamespaceOption(); public Resource getNamespaceOption(); public boolean hasDeclarationsOption(); public String getDeclarationsOption(); public boolean hasPropertySectionOption(); public String getPropertySectionOption(); public boolean hasClassSectionOption(); public String getClassSectionOption(); public boolean hasIndividualsSectionOption(); public String getIndividualsSectionOption(); public boolean hasNopropertiesOption(); public boolean hasNoclassesOption(); public boolean hasNoindividualsOption(); public boolean hasPropTemplateOption(); public String getPropTemplateOption(); public boolean hasClassTemplateOption(); public String getClassTemplateOption(); public boolean hasIndividualTemplateOption(); public String getIndividualTemplateOption(); public boolean hasUcNamesOption(); public boolean hasIncludeOption(); public List getIncludeOption(); public boolean hasClassnameSuffixOption(); public String getClassnameSuffixOption(); public boolean hasNoheaderOption(); public boolean hasEncodingOption(); public String getEncodingOption(); public boolean hasHelpOption(); public String getHelpOption(); public boolean hasDosOption(); public boolean hasUseInfOption(); public boolean hasStrictIndividualsOption(); public boolean hasIncludeSourceOption(); public boolean hasNoStrictOption(); } public static class SchemagenOptionsImpl implements SchemagenOptions { // Instance variables /** The list of command line arguments */ private List m_cmdLineArgs = new ArrayList(); /** The root of the options in the config file */ private Resource m_root; /** The model that contains the configuration information */ private Model m_config = ModelFactory.createDefaultModel(); // Constructor public SchemagenOptionsImpl( String[] args ) { m_cmdLineArgs = Arrays.asList( args ); // check to see if there's a specified config file String configURL = DEFAULT_CONFIG_URI; if (hasConfigFileOption()) { // check for protocol; add file: if not specified configURL = SchemagenUtils.urlCheck( getConfigFileOption() ); } // ensure we have a root URI for the configuration model determineConfigRoot(); // try to read the config URI try { FileManager.get().readModel( m_config, configURL ); } catch (Exception e) { // if the user left the default config URI in place, it's not an error to fail to read it if (!configURL.equals( DEFAULT_CONFIG_URI )) { throw new SchemagenException( "Failed to read configuration from URL: " + configURL, e ); } } } /** * Return the configuration model used to hold config information * @return */ protected Model getConfigModel() { return m_config; } /** * Return the root resource to which configuration information is attached * @return */ protected Resource getConfigRoot() { if (m_root == null) { determineConfigRoot(); } return m_root; } // Internal implementation methods /** Determine the root resource in the configuration file */ protected void determineConfigRoot() { if (hasValue( OPT.ROOT )) { m_root = m_config.getResource( getStringValue( OPT.ROOT ) ); } else { // no specified root, we assume there is only one with type sgen:Config StmtIterator i = m_config.listStatements( null, RDF.type, m_config.getResource( NS + "Config" ) ); if (i.hasNext()) { m_root = i.nextStatement().getSubject(); } else { // no configuration root, so we invent one m_root = m_config.createResource(); } } } /** Answer true if the given option is set to true */ protected boolean isTrue( OPT option ) { return getOpt( option ).isTrue( m_cmdLineArgs, m_root ); } /** Answer true if the given option has value */ protected boolean hasValue( OPT option ) { return getOpt( option ).hasValue( m_cmdLineArgs, m_root ); } /** Answer the value of the option or null */ protected RDFNode getValue( OPT option ) { return getOpt( option ).getValue( m_cmdLineArgs, m_root ); } /** Answer the String value of the option or null */ protected String getStringValue( OPT option ) { return getOpt( option ).getStringValue( m_cmdLineArgs, m_root ); } /** Answer true if the given option has a resource value */ protected boolean hasResourceValue( OPT option ) { return getOpt( option ).hasResourceValue( m_cmdLineArgs, m_root ); } /** Answer the value of the option or null */ protected Resource getResource( OPT option ) { return getOpt( option ).getResource( m_cmdLineArgs, m_root ); } /** Answer all values for the given options as Strings */ protected List getAllValues( OPT option ) { List values = new ArrayList(); OptionDefinition opt = getOpt( option ); // look in the command line arguments for (Iterator i = m_cmdLineArgs.iterator(); i.hasNext(); ) { String s = i.next(); if (s.equals( opt.m_cmdLineForm )) { // next iterator value is the arg value values.add( i.next() ); } } // now look in the config file for (StmtIterator i = m_root.listProperties( opt.m_prop ); i.hasNext(); ) { Statement s = i.nextStatement(); if (s.getObject() instanceof Literal) { values.add( s.getString() ); } else { values.add( s.getResource().getURI() ); } } return values; } /** Answer the option object for the given option */ protected OptionDefinition getOpt( OPT option ) { for (int i = 0; i < m_optionDefinitions.length; i++) { if (m_optionDefinitions[i][0] == option) { return (OptionDefinition) m_optionDefinitions[i][1]; } } return null; } // External interface methods public boolean hasConfigFileOption() { return hasValue( OPT.CONFIG_FILE ); } public String getConfigFileOption() { return getStringValue( OPT.CONFIG_FILE ); } public boolean hasRootOption() { return hasValue( OPT.ROOT ); } public String getRootOption() { return getStringValue( OPT.ROOT ); } public boolean hasNoCommentsOption() { return isTrue( OPT.NO_COMMENTS ); } public String getNoCommentsOption() { return getStringValue( OPT.NO_COMMENTS ); } public boolean hasInputOption() { return hasValue( OPT.INPUT ); } public Resource getInputOption() { return getResource( OPT.INPUT ); } public boolean hasLangDamlOption() { return isTrue( OPT.LANG_DAML ); } public String getLangDamlOption() { return getStringValue( OPT.LANG_DAML ); } public boolean hasLangOwlOption() { return isTrue( OPT.LANG_OWL ); } public String getLangOwlOption() { return getStringValue( OPT.LANG_OWL ); } public boolean hasLangRdfsOption() { return isTrue( OPT.LANG_RDFS ); } public String getLangRdfsOption() { return getStringValue( OPT.LANG_RDFS ); } public boolean hasOutputOption() { return hasValue( OPT.OUTPUT ); } public String getOutputOption() { return getStringValue( OPT.OUTPUT ); } public boolean hasHeaderOption() { return isTrue( OPT.HEADER ); } public String getHeaderOption() { return getStringValue( OPT.HEADER ); } public boolean hasFooterOption() { return isTrue( OPT.FOOTER ); } public String getFooterOption() { return getStringValue( OPT.FOOTER ); } public boolean hasMarkerOption() { return hasValue( OPT.MARKER ); } public String getMarkerOption() { return getStringValue( OPT.MARKER ); } public boolean hasPackagenameOption() { return hasValue( OPT.PACKAGENAME ); } public String getPackagenameOption() { return getStringValue( OPT.PACKAGENAME ); } public boolean hasOntologyOption() { return isTrue( OPT.ONTOLOGY ); } public String getOntologyOption() { return getStringValue( OPT.ONTOLOGY ); } public boolean hasClassnameOption() { return hasValue( OPT.CLASSNAME ); } public String getClassnameOption() { return getStringValue( OPT.CLASSNAME ); } public boolean hasClassdecOption() { return hasValue( OPT.CLASSDEC ); } public String getClassdecOption() { return getStringValue( OPT.CLASSDEC ); } public boolean hasNamespaceOption() { return hasValue( OPT.NAMESPACE ); } public Resource getNamespaceOption() { return getResource( OPT.NAMESPACE ); } public boolean hasDeclarationsOption() { return hasValue( OPT.DECLARATIONS ); } public String getDeclarationsOption() { return getStringValue( OPT.DECLARATIONS ); } public boolean hasPropertySectionOption() { return hasValue( OPT.PROPERTY_SECTION ); } public String getPropertySectionOption() { return getStringValue( OPT.PROPERTY_SECTION ); } public boolean hasClassSectionOption() { return hasValue( OPT.CLASS_SECTION ); } public String getClassSectionOption() { return getStringValue( OPT.CLASS_SECTION ); } public boolean hasIndividualsSectionOption() { return hasValue( OPT.INDIVIDUALS_SECTION ); } public String getIndividualsSectionOption() { return getStringValue( OPT.INDIVIDUALS_SECTION ); } public boolean hasNopropertiesOption() { return isTrue( OPT.NOPROPERTIES ); } public boolean hasNoclassesOption() { return isTrue( OPT.NOCLASSES ); } public boolean hasNoindividualsOption() { return isTrue( OPT.NOINDIVIDUALS ); } public boolean hasPropTemplateOption() { return hasValue( OPT.PROP_TEMPLATE ); } public String getPropTemplateOption() { return getStringValue( OPT.PROP_TEMPLATE ); } public boolean hasClassTemplateOption() { return hasValue( OPT.CLASS_TEMPLATE ); } public String getClassTemplateOption() { return getStringValue( OPT.CLASS_TEMPLATE ); } public boolean hasIndividualTemplateOption() { return hasValue( OPT.INDIVIDUAL_TEMPLATE ); } public String getIndividualTemplateOption() { return getStringValue( OPT.INDIVIDUAL_TEMPLATE ); } public boolean hasUcNamesOption() { return isTrue( OPT.UC_NAMES ); } public boolean hasIncludeOption() { return hasValue( OPT.INCLUDE ); } public List getIncludeOption() { return getAllValues( OPT.INCLUDE ); } public boolean hasClassnameSuffixOption() { return hasValue( OPT.CLASSNAME_SUFFIX ); } public String getClassnameSuffixOption() { return getStringValue( OPT.CLASSNAME_SUFFIX ); } public boolean hasNoheaderOption() { return isTrue( OPT.NOHEADER ); } public boolean hasEncodingOption() { return hasValue( OPT.ENCODING ); } public String getEncodingOption() { return getStringValue( OPT.ENCODING ); } public boolean hasHelpOption() { return hasValue( OPT.HELP ); } public String getHelpOption() { return getStringValue( OPT.HELP ); } public boolean hasDosOption() { return isTrue( OPT.DOS ); } public boolean hasUseInfOption() { return isTrue( OPT.USE_INF ); } public boolean hasStrictIndividualsOption() { return isTrue( OPT.STRICT_INDIVIDUALS ); } public boolean hasIncludeSourceOption() { return isTrue( OPT.INCLUDE_SOURCE ); } public boolean hasNoStrictOption() { return isTrue( OPT.NO_STRICT ); } } /** An option that can be set either on the command line or in the RDF config */ public static class OptionDefinition { protected String m_cmdLineForm; protected Property m_prop; protected OptionDefinition( String cmdLineForm, String name ) { m_cmdLineForm = cmdLineForm; if (name != null) { m_prop = ResourceFactory.createProperty( NS, name ); } } /** * Return the RDF property that is used when configuring this option * via a {@link Model} * @return The declaration property, or null */ public Property getDeclarationProperty() { return m_prop; } /** * Return the command line form of this option * @return The command line form as a String */ public String getCommandLineForm() { return m_cmdLineForm; } /** * Answer true if this option is set to true, either on the command line * or in the config model * * @return boolean */ protected boolean isTrue( List cmdLineArgs, Resource confRoot ) { if (cmdLineArgs.contains( m_cmdLineForm )) { return true; } if (confRoot.hasProperty( m_prop )) { return confRoot.getRequiredProperty( m_prop ).getBoolean(); } return false; } /** * Answer the string value of the parameter if set, or null otherwise. Note command line * has precedence. * * @return String */ protected String getStringValue( List cmdLineArgs, Resource confRoot ) { RDFNode n = getValue( cmdLineArgs, confRoot ); return (n == null) ? null : (n.isLiteral() ? n.asLiteral().getLexicalForm() : n.toString() ); } /** * Return the value of the parameter if set, or null otherwise. Note command line * has precedence. * * @return The argument value as an RDFNode */ protected RDFNode getValue( List cmdLineArgs, Resource confRoot ) { int index = cmdLineArgs.indexOf( m_cmdLineForm ); if (index >= 0) { try { return ResourceFactory.createPlainLiteral( cmdLineArgs.get( index + 1 ) ); } catch (IndexOutOfBoundsException e) { throw new SchemagenException( "Value for parameter " + m_cmdLineForm + " not set! Aborting.", e ); } } if (m_prop != null && confRoot != null && confRoot.hasProperty( m_prop )) { return confRoot.getRequiredProperty( m_prop ).getObject(); } // not set return null; } /** * Answer true if the parameter has a value at all. * * @return boolean */ protected boolean hasValue( List cmdLineArgs, Resource confRoot ) { return getValue( cmdLineArgs, confRoot ) != null; } /** * Answer the resource value of the parameter if set, or null otherwise. * * @return String */ protected Resource getResource( List cmdLineArgs, Resource confRoot ) { int index = cmdLineArgs.indexOf( m_cmdLineForm ); if (index >= 0) { try { return confRoot.getModel().getResource( cmdLineArgs.get( index + 1 ) ); } catch (IndexOutOfBoundsException e) { System.err.println( "Value for parameter " + m_cmdLineForm + " not set! Aborting."); } } if (m_prop != null && confRoot.hasProperty( m_prop )) { return confRoot.getRequiredProperty( m_prop ).getResource(); } // not set return null; } /** * Answer true if the parameter has a value at all. * * @return boolean */ protected boolean hasResourceValue( List cmdLineArgs, Resource confRoot ) { return getResource( cmdLineArgs, confRoot ) != null; } } // end inner class OptionDefinition /** A pairing of pattern and substitution we want to apply to output */ protected class Replacement { protected String sub; protected Pattern pattern; protected Replacement( Pattern pattern, String sub) { this.sub = sub; this.pattern = pattern; } } // end inner class Replacement /** *

Schemagen runtime exception

*/ public static class SchemagenException extends RuntimeException { public SchemagenException( String msg, Throwable cause ) { super( msg, cause ); } } /** Utility method container */ public static class SchemagenUtils { /** Return a URI formed from the given string, unchanged if it's already a URI or * converted to a file URI otherwise. If not recognisable as a URL, abort. */ public static String urlCheck( String uriOrFile ) { boolean legal = true; String url = uriOrFile; // is it a URI already? to check, we make a URL and see what happens! try { new URL( url ); } catch (MalformedURLException ignore) { legal = false; } // if not a legal url, assume it's a file if (!legal) { legal = true; String slash = System.getProperty( "file.separator" ); url = "file:" + (uriOrFile.startsWith( slash ) ? (slash + slash) : "") + uriOrFile; try { new URL( url ); } catch (MalformedURLException ignore) { legal = false; } } if (!legal) { throw new SchemagenException( "Could not parse " + uriOrFile + " as a legal URL or a file reference. Aborting.", null ); } return url; } } /* End class SchemagenUtils */ } /* (c) Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */




© 2015 - 2025 Weber Informatics LLC | Privacy Policy