| /************************************************************************ |
| * |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER |
| * |
| * Copyright 2009, 2010 Oracle and/or its affiliates. All rights reserved. |
| * |
| * Use is subject to license terms. |
| * |
| * Licensed 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. You can also |
| * obtain a copy of the License at http://odftoolkit.org/docs/license.txt |
| * |
| * 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 schema2template.example.odf; |
| |
| import com.sun.msv.grammar.Expression; |
| import com.sun.msv.grammar.NameClassAndExpression; |
| import com.sun.msv.reader.trex.ng.RELAXNGReader; |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.SortedSet; |
| import java.util.TreeSet; |
| import javax.xml.parsers.SAXParserFactory; |
| import schema2template.model.PuzzlePiece; |
| import schema2template.model.PuzzlePieceSet; |
| import schema2template.model.MSVExpressionInformation; |
| import schema2template.model.MSVExpressionType; |
| import schema2template.model.MSVExpressionVisitorType; |
| import schema2template.model.MSVNameClassVisitorList; |
| |
| /** |
| * ODF example class to print the MSV expressions in between a PuzzlePiece parent element |
| * and a direct PuzzlePiece child element. |
| * |
| * <p>Example of a direct child: table:table -> table:table-row<br /> |
| * Example of a non-direct child: table:table -> table:table-cell</p> |
| * |
| * <p>Directly change the string constants EXAMPLE_PARENT and EXAMPLE_CHILD in |
| * the source code to set parent and child element.</p> |
| */ |
| public class PathPrinter { |
| |
| // CHANGE THIS... |
| public final static String EXAMPLE_PARENT = "table:table"; |
| public final static String EXAMPLE_CHILD = "table:table-row"; |
| PuzzlePiece mParent; |
| MSVExpressionInformation mInfo; |
| public final static String ODF_RESOURCE_DIR = "target" + File.separator + "classes" |
| + File.separator + "examples" + File.separator + "odf"; |
| |
| PathPrinter(PuzzlePiece parent) { |
| mParent = parent; |
| mInfo = new MSVExpressionInformation(parent.getExpression()); |
| } |
| |
| /** |
| * Map Name to PuzzlePiece(s). |
| */ |
| static Map<String, SortedSet<PuzzlePiece>> createDefinitionMap(Set<PuzzlePiece> definitions) { |
| Map<String, SortedSet<PuzzlePiece>> retval = new HashMap<String, SortedSet<PuzzlePiece>>(); |
| Iterator<PuzzlePiece> iter = definitions.iterator(); |
| while (iter.hasNext()) { |
| PuzzlePiece def = iter.next(); |
| SortedSet<PuzzlePiece> multiples = retval.get(def.getQName()); |
| if (multiples == null) { |
| multiples = new TreeSet<PuzzlePiece>(); |
| retval.put(def.getQName(), multiples); |
| } |
| multiples.add(def); |
| } |
| return retval; |
| } |
| |
| List<String> printPathsToChild(PuzzlePiece child) { |
| MSVExpressionVisitorType typeVisitor = new MSVExpressionVisitorType(); |
| List<List<Expression>> paths = null; |
| if (child != null) { |
| paths = mInfo.getPathsContaining(child.getExpression()); |
| } else { |
| paths = mInfo.getPathsContaining(mParent.getExpression()); |
| } |
| if (paths == null) { |
| return null; |
| } |
| MSVNameClassVisitorList nameVisitor = new MSVNameClassVisitorList(); |
| |
| List<String> retval = new ArrayList<String>(paths.size()); |
| for (List<Expression> path : paths) { |
| boolean first = true; |
| String wayString = ""; |
| for (Expression step : path) { |
| MSVExpressionType type = (MSVExpressionType) step.visit(typeVisitor); |
| if (type == MSVExpressionType.REF) { |
| continue; |
| } |
| String name = type.toString(); |
| String qname = ""; |
| // NameClassAndExpression is an MSV class for abstract named expressions (ie. attributes and elements) |
| if (step instanceof NameClassAndExpression) { |
| List<String> names = (List<String>) ((NameClassAndExpression) step).getNameClass().visit(nameVisitor); |
| if (names != null) { |
| boolean firstQ = true; |
| for (String singleQ : names) { |
| if (firstQ) { |
| firstQ = false; |
| qname = singleQ; |
| } else { |
| qname += "," + singleQ; |
| } |
| } |
| } |
| } |
| if (first) { |
| first = false; |
| wayString = name + " " + qname; |
| } else { |
| if (step instanceof NameClassAndExpression) { |
| name = name + " " + qname; |
| } |
| wayString = wayString.concat(" -> " + name); |
| } |
| } |
| retval.add(wayString); |
| } |
| return retval; |
| } |
| |
| private static Expression parseOdfSchema(File rngFile) throws Exception { |
| SAXParserFactory factory = SAXParserFactory.newInstance(); |
| factory.setNamespaceAware(true); |
| |
| Expression root = RELAXNGReader.parse( |
| rngFile.getAbsolutePath(), |
| factory, |
| new com.sun.msv.reader.util.IgnoreController()).getTopLevel(); |
| |
| if (root == null) { |
| throw new Exception("Schema could not be parsed."); |
| } |
| return root; |
| } |
| |
| public static void main(String[] args) throws Exception { |
| Expression root = parseOdfSchema(new File(ODF_RESOURCE_DIR + File.separator + OdfHelper.ODF12_RNG_FILE_NAME)); |
| PuzzlePieceSet elements = new PuzzlePieceSet(); |
| PuzzlePieceSet attributes = new PuzzlePieceSet(); |
| PuzzlePiece.extractPuzzlePieces(root, elements, attributes); |
| Map<String, SortedSet<PuzzlePiece>> nameToDefinition = createDefinitionMap(new TreeSet<PuzzlePiece>(elements)); |
| |
| System.out.println("Print all paths from parent element (e.g. \"text:p\") to direct child element (e.g. \"text:span\")"); |
| |
| SortedSet<PuzzlePiece> pieces = nameToDefinition.get(EXAMPLE_PARENT); |
| |
| if (pieces == null) { |
| System.out.println("No parent element found by the given name: " + EXAMPLE_PARENT); |
| } |
| |
| PuzzlePiece parent = pieces.first(); |
| |
| pieces = nameToDefinition.get(EXAMPLE_CHILD); |
| |
| if (pieces == null) { |
| System.out.println("No child element found by the given name: " + EXAMPLE_CHILD); |
| } |
| |
| PuzzlePiece child = pieces.first(); |
| |
| if (pieces.size() > 1) { |
| System.out.println("There were more than one element by this name. Dropped all instances but one."); |
| } |
| |
| System.out.println(); |
| System.out.println("PATHS from " + parent.getQName() + " to " + child.getQName() + ": "); |
| System.out.println("---------------------------------------------------------"); |
| |
| List<String> paths = new PathPrinter(parent).printPathsToChild(child); |
| |
| if (paths == null) { |
| System.out.println("No Path found."); |
| } else { |
| for (String s : paths) { |
| System.out.println(s); |
| } |
| } |
| } |
| } |