001: /**********************************************************************
002: Copyright (c) 2006 Andy Jefferson and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015: Contributors:
016: ...
017: **********************************************************************/package org.jpox.metadata.xml;
018:
019: import org.xml.sax.Attributes;
020: import org.xml.sax.EntityResolver;
021: import org.xml.sax.SAXException;
022:
023: import org.jpox.metadata.MetaData;
024: import org.jpox.metadata.MetaDataManager;
025: import org.jpox.metadata.PersistenceFileMetaData;
026: import org.jpox.metadata.PersistenceUnitMetaData;
027: import org.jpox.util.JPOXLogger;
028:
029: /**
030: * Parser handler for "persistence.xml" files to convert them into a PersistenceFileMetaData.
031: * Implements DefaultHandler and handles the extracting of MetaData from the
032: * XML elements/attributes. This class simply constructs the MetaData representation
033: * mirroring what is in the MetaData file.
034: * <P>Operates the parse process using a Stack. MetaData components are added
035: * to the stack as they are encountered and created. They are then popped off
036: * the stack when the end element is encountered.</P>
037: *
038: * @since 1.1
039: * @version $Revision: 1.2 $
040: */
041: public class PersistenceFileMetaDataHandler extends
042: AbstractMetaDataHandler {
043: /**
044: * Constructor. Protected to prevent instantiation.
045: * @param mgr the metadata manager
046: * @param filename The name of the file to parse
047: * @param resolver Entity Resolver to use (null if not available)
048: */
049: public PersistenceFileMetaDataHandler(MetaDataManager mgr,
050: String filename, EntityResolver resolver) {
051: super (mgr, filename, resolver);
052: metadata = new PersistenceFileMetaData(filename);
053: pushStack(metadata);
054: }
055:
056: /**
057: * Handler method called at the start of an element.
058: * @param uri URI of the tag
059: * @param localName Local name
060: * @param qName Element name
061: * @param attrs Attributes for this element
062: * @throws SAXException in parsing errors
063: */
064: public void startElement(String uri, String localName,
065: String qName, Attributes attrs) throws SAXException {
066: if (JPOXLogger.METADATA.isDebugEnabled()) {
067: StringBuffer sb = new StringBuffer();
068: sb.append("<" + qName);
069: for (int i = 0; i < attrs.getLength(); i++) {
070: sb.append(" ");
071: sb.append(attrs.getQName(i)).append("=\"").append(
072: attrs.getValue(i)).append("\"");
073: }
074: sb.append(">");
075: JPOXLogger.METADATA.debug(LOCALISER.msg("044034", sb
076: .toString(), "" + stack.size()));
077: }
078: if (localName.length() < 1) {
079: localName = qName;
080: }
081: try {
082: if (localName.equals("persistence")) {
083: // New "persistence" file
084: // Do nothing - created in our constructor
085: } else if (localName.equals("persistence-unit")) {
086: // New "persistence-unit"
087: PersistenceFileMetaData filemd = (PersistenceFileMetaData) getStack();
088: PersistenceUnitMetaData pumd = new PersistenceUnitMetaData(
089: filemd, getAttr(attrs, "name"), getAttr(attrs,
090: "transaction-type"));
091: filemd.addPersistenceUnit(pumd);
092: pushStack(pumd);
093: } else if (localName.equals("properties")) {
094: // Do nothing
095: } else if (localName.equals("property")) {
096: // New "property" for the current persistence unit
097: PersistenceUnitMetaData pumd = (PersistenceUnitMetaData) getStack();
098: pumd.addProperty(getAttr(attrs, "name"), getAttr(attrs,
099: "value"));
100: } else if (localName.equals("mapping-file")) {
101: // Processed elsewhere
102: } else if (localName.equals("class")) {
103: // Processed elsewhere
104: } else if (localName.equals("jar-file")) {
105: // Processed elsewhere
106: } else if (localName.equals("jta-data-source")) {
107: // Processed elsewhere
108: } else if (localName.equals("non-jta-data-source")) {
109: // Processed elsewhere
110: } else if (localName.equals("description")) {
111: // Processed elsewhere
112: } else if (localName.equals("provider")) {
113: // Processed elsewhere
114: } else if (localName.equals("exclude-unlisted-classes")) {
115: PersistenceUnitMetaData pumd = (PersistenceUnitMetaData) getStack();
116: pumd.setExcludeUnlistedClasses();
117: } else {
118: String message = LOCALISER.msg("044037", qName);
119: JPOXLogger.METADATA.error(message);
120: throw new RuntimeException(message);
121: }
122: } catch (RuntimeException ex) {
123: JPOXLogger.METADATA.error(LOCALISER.msg("044042", qName,
124: getStack(), uri), ex);
125: throw ex;
126: }
127: }
128:
129: /**
130: * Handler method called at the end of an element.
131: * @param uri URI of the tag
132: * @param localName local name
133: * @param qName Name of element just ending
134: * @throws SAXException in parsing errors
135: */
136: public void endElement(String uri, String localName, String qName)
137: throws SAXException {
138: if (JPOXLogger.METADATA.isDebugEnabled()) {
139: JPOXLogger.METADATA.debug(LOCALISER.msg("044035", "<"
140: + qName + ">", "" + stack.size()));
141: }
142: if (localName.length() < 1) {
143: localName = qName;
144: }
145:
146: // Save the current string for elements that have a body value
147: String currentString = getString().trim();
148: if (currentString.length() > 0) {
149: MetaData md = getStack();
150: if (localName.equals("description")) {
151: // Unit description
152: ((PersistenceUnitMetaData) md)
153: .setDescription(currentString);
154: } else if (localName.equals("provider")) {
155: // Unit provider
156: ((PersistenceUnitMetaData) md)
157: .setProvider(currentString);
158: } else if (localName.equals("jta-data-source")) {
159: // JTA data source
160: ((PersistenceUnitMetaData) md)
161: .setJtaDataSource(currentString);
162: } else if (localName.equals("non-jta-data-source")) {
163: // Non-JTA data source
164: ((PersistenceUnitMetaData) md)
165: .setNonJtaDataSource(currentString);
166: } else if (localName.equals("class")) {
167: // New persistent class
168: ((PersistenceUnitMetaData) md)
169: .addClassName(currentString);
170: } else if (localName.equals("mapping-file")) {
171: // New mapping file
172: ((PersistenceUnitMetaData) md)
173: .addMappingFile(currentString);
174: } else if (localName.equals("jar-file")) {
175: // New jar file
176: ((PersistenceUnitMetaData) md)
177: .addJarFile(currentString);
178: }
179: }
180:
181: // Pop the tag
182: // If startElement pushes an element onto the stack need a remove here for that type
183: if (qName.equals("persistence-unit")) {
184: popStack();
185: }
186: }
187: }
|