001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.schema2beansdev;
043:
044: import java.io.*;
045: import java.util.*;
046:
047: /**
048: * EntityParser.java - parses the DTD file for entity declarations and creates new Reader
049: * that replaces the entity references with values
050: *
051: * Created on June 11, 2005 AM
052: * @author mkuchtiak
053: */
054: public class EntityParser {
055: private java.util.Map entityMap;
056: private File fileName;
057:
058: /** Creates a new instance of EntityParser */
059: public EntityParser(File fileName) {
060: this .fileName = fileName;
061: entityMap = new java.util.HashMap();
062: }
063:
064: /** Parses file for ENTITY declaration, creates map with entities
065: */
066: public void parse() throws IOException {
067: BufferedReader br = new BufferedReader(new FileReader(fileName));
068: String line = null;
069: while ((line = br.readLine()) != null) {
070: int startPos = line.indexOf("<!ENTITY ");
071: if (startPos >= 0)
072: addEntity(br, line.substring(startPos + 9));
073: }
074: br.close();
075: }
076:
077: private void addEntity(BufferedReader br, String line)
078: throws IOException {
079: StringTokenizer tok = new StringTokenizer(line);
080: if (!tok.hasMoreTokens())
081: return;
082: String percentage = tok.nextToken();
083: if (!"%".equals(percentage))
084: return; //incorrect ENTITY declaration (missing %)
085: if (!tok.hasMoreTokens())
086: return; //incorrect ENTITY declaration (missing entity name)
087:
088: // cut the first part including entity key
089: String key = tok.nextToken();
090: int valueStartPos = line.indexOf(key) + key.length();
091: String rest = line.substring(valueStartPos);
092:
093: // looking for starting quotes
094: valueStartPos = rest.indexOf("\"");
095: if (valueStartPos < 0)
096: return;
097:
098: // looking for entity value
099: rest = rest.substring(valueStartPos + 1);
100: String value = resolveValue(rest, br);
101:
102: // write ENTITY into map
103: if (value != null) {
104: int refStart = value.indexOf("%");
105: int refEnd = value.indexOf(";");
106: if (refStart >= 0 && refEnd > refStart) { //references other entity
107: String entityKey = value
108: .substring(refStart + 1, refEnd);
109: String val = (String) entityMap.get(entityKey);
110: if (val != null) {
111: String newValue = value.substring(0, refStart)
112: + val + value.substring(refEnd + 1);
113: System.out.println("found ENTITY: % " + key + " \""
114: + newValue + "\"");
115: entityMap.put(key, newValue);
116: }
117: } else {
118: System.out.println("found ENTITY: % " + key + " \""
119: + value + "\"");
120: entityMap.put(key, value);
121: }
122: }
123: }
124:
125: private String resolveValue(String lineRest, BufferedReader br)
126: throws IOException {
127: // looking for closing quotes
128: int index = lineRest.indexOf("\"");
129: if (index >= 0)
130: return lineRest.substring(0, index);
131: // value across multiple lines
132: StringBuffer buf = new StringBuffer(lineRest);
133: buf.append("\n");
134: int ch = br.read();
135: while (ch != (int) '"' && ch != (int) '>' && ch != -1) {
136: buf.append((char) ch);
137: ch = br.read();
138: }
139: return buf.toString();
140: }
141:
142: private boolean containsBlank(String s) {
143: for (int i = 0; i < s.length(); i++) {
144: if (' ' == s.charAt(i))
145: return true;
146: }
147: return false;
148: }
149:
150: /** Creates a StringReader that removes all ENTITY declarations
151: * and replaces entity references with corresponding values
152: */
153: public Reader getReader() throws IOException {
154: StringBuffer buf = new StringBuffer();
155: BufferedReader br = new BufferedReader(new FileReader(fileName));
156: String line = null;
157: while ((line = br.readLine()) != null) {
158: // removing line(s) with entity declaration
159: if (line.indexOf("<!ENTITY ") >= 0)
160: line = removeEntityDeclaration(line, br);
161: // searches for entity reference and replace it with value
162: int pos = line.indexOf("%");
163: if (pos >= 0) {
164: StringTokenizer tok = new StringTokenizer(line
165: .substring(pos), ";%");
166: while (tok.hasMoreTokens()) {
167: String key = tok.nextToken();
168: if (key.length() > 0 && !containsBlank(key)) {
169: String value = (String) entityMap.get(key);
170: if (value != null)
171: line = line.replaceAll("%" + key + ";",
172: value);
173: }
174: }
175: }
176: if (line.length() > 0)
177: buf.append(line);
178: }
179: br.close();
180: return new StringReader(buf.toString());
181: }
182:
183: /** Removing line(s) containing ENTITY declaration
184: */
185: private String removeEntityDeclaration(String line,
186: BufferedReader br) throws IOException {
187: int start = line.indexOf("<!ENTITY ");
188: StringBuffer buf = new StringBuffer();
189: if (start > 0)
190: buf.append(line.substring(0, start));
191: int endPos = line.indexOf(">", start);
192: if (endPos > 0) {
193: buf.append(line.substring(endPos + 1));
194: return buf.toString();
195: }
196: String ln = null;
197: while (endPos < 0 && (ln = br.readLine()) != null) {
198: endPos = ln.indexOf(">");
199: if (endPos >= 0) {
200: buf.append(ln.substring(endPos + 1));
201: }
202: }
203: return buf.toString();
204: }
205:
206: }
|