001: package com.jclark.xml.apps;
002:
003: import java.io.*;
004: import java.util.Enumeration;
005: import com.jclark.xml.parse.*;
006: import com.jclark.xml.parse.io.*;
007: import com.jclark.xml.output.*;
008:
009: /**
010: * @version $Revision: 1.2 $ $Date: 1998/06/25 09:28:53 $
011: */
012: public class Doctype extends ApplicationImpl {
013:
014: private static final String attTypeNames[] = new String[] {
015: "CDATA", "ID", "IDREF", "IDREFS", "ENTITY", "ENTITIES",
016: "NMTOKEN", "NMTOKENS", null, "NOTATION" };
017:
018: private final PrintWriter w;
019: private int openEntityCount = 0;
020: private boolean inDoctype = false;
021:
022: /**
023: * Writes an equivalent version of the doctype declaration
024: * on the standard output.
025: * If an argument is specified, then that is treated as the filename
026: * of the XML document, otherwise the XML document is read from the
027: * standard input.
028: */
029: public static void main(String args[]) throws IOException {
030: if (args.length > 1) {
031: System.err
032: .println("usage: jview com.jclark.xml.apps.Doctype [file]");
033: System.exit(1);
034: }
035: Parser parser = new ParserImpl();
036: parser.setApplication(new Doctype(new PrintWriter(
037: new FileOutputStream(FileDescriptor.out))));
038: try {
039: parser.parseDocument(args.length == 0 ? EntityManagerImpl
040: .openStandardInput() : EntityManagerImpl
041: .openFile(args[0]));
042: } catch (NotWellFormedException e) {
043: System.err.println(e.getMessage());
044: System.exit(1);
045: }
046: }
047:
048: public Doctype(PrintWriter w) {
049: this .w = w;
050: }
051:
052: public void startDocumentTypeDeclaration(
053: StartDocumentTypeDeclarationEvent event) {
054: DTD dtd = event.getDTD();
055: w.print("<!DOCTYPE " + dtd.getDocumentTypeName() + " ");
056: Entity entity = dtd.getEntity(DTD.PARAMETER_ENTITY,
057: DTD.EXTERNAL_SUBSET_NAME);
058: if (entity != null) {
059: writeExternalId(entity);
060: w.println(" [");
061: } else
062: w.println("[");
063: inDoctype = true;
064: }
065:
066: public void endDocumentTypeDeclaration(
067: EndDocumentTypeDeclarationEvent event) {
068: inDoctype = false;
069: w.println("]>");
070: w.flush();
071: }
072:
073: public void startEntityReference(StartEntityReferenceEvent event) {
074: if (inDoctype) {
075: if (openEntityCount++ == 0
076: && !event.getName().equals("#DOCTYPE"))
077: w.println("%" + event.getName() + ";");
078: }
079: }
080:
081: public void endEntityReference(EndEntityReferenceEvent event) {
082: if (inDoctype)
083: --openEntityCount;
084: }
085:
086: public void processingInstruction(ProcessingInstructionEvent event) {
087: if (openEntityCount == 0 && inDoctype)
088: w.println("<?" + event.getName() + " "
089: + event.getInstruction() + "?>");
090: }
091:
092: public void comment(CommentEvent event) {
093: if (openEntityCount == 0 && inDoctype)
094: w.println("<!--" + event.getComment() + "-->");
095: }
096:
097: public void markupDeclaration(MarkupDeclarationEvent event) {
098: if (openEntityCount != 0)
099: return;
100: String name = event.getName();
101: DTD dtd = event.getDTD();
102: switch (event.getType()) {
103: case MarkupDeclarationEvent.ELEMENT:
104: writeElementDecl(dtd, name);
105: break;
106: case MarkupDeclarationEvent.GENERAL_ENTITY:
107: writeEntityDecl(dtd, DTD.GENERAL_ENTITY, name);
108: break;
109: case MarkupDeclarationEvent.PARAMETER_ENTITY:
110: writeEntityDecl(dtd, DTD.PARAMETER_ENTITY, name);
111: break;
112: case MarkupDeclarationEvent.NOTATION:
113: writeEntityDecl(dtd, DTD.NOTATION, name);
114: break;
115: case MarkupDeclarationEvent.ATTRIBUTE:
116: writeAttributeDef(dtd, name, event.getAttributeName());
117: break;
118: }
119: }
120:
121: public void writeEntityDecl(DTD dtd, byte type, String name) {
122: switch (type) {
123: case DTD.GENERAL_ENTITY:
124: w.print("<!ENTITY ");
125: break;
126: case DTD.PARAMETER_ENTITY:
127: w.print("<!ENTITY % ");
128: break;
129: case DTD.NOTATION:
130: w.print("<!NOTATION ");
131: break;
132: }
133: w.print(name + " ");
134: Entity entity = dtd.getEntity(type, name);
135: String text = entity.getReplacementText();
136: if (text == null) {
137: writeExternalId(entity);
138: if (type == DTD.GENERAL_ENTITY) {
139: name = entity.getNotationName();
140: if (name != null)
141: w.print(" NDATA " + name);
142: }
143: } else {
144: w.print('"');
145: for (int i = 0; i < text.length(); i++) {
146: char c = text.charAt(i);
147: switch (c) {
148: case '&':
149: case '"':
150: case '%':
151: case 13:
152: w.print("&#" + (int) c + ";");
153: break;
154: default:
155: w.print(c);
156: break;
157: }
158: }
159: w.print('"');
160: }
161: w.println(">");
162: }
163:
164: public void writeElementDecl(DTD dtd, String name) {
165: w.println("<!ELEMENT " + name + " "
166: + dtd.getElementType(name).getContentSpec() + ">");
167: }
168:
169: public void writeAttributeDef(DTD dtd, String name, String attName) {
170: AttributeDefinition def = dtd.getElementType(name)
171: .getAttributeDefinition(attName);
172: w.print("<!ATTLIST " + name + " " + attName);
173: String type = attTypeNames[def.getType()];
174: if (type != null)
175: w.print(" " + type);
176: Enumeration allowEnum = def.allowedValues();
177: if (allowEnum != null) {
178: w.print(" (" + (String) allowEnum.nextElement());
179: while (allowEnum.hasMoreElements())
180: w.print((String) allowEnum.nextElement());
181: w.print(")");
182: }
183: String value = def.getDefaultUnnormalizedValue();
184: boolean required = def.isRequired();
185: if (value == null)
186: w.print(required ? " #REQUIRED" : " #IMPLIED");
187: else {
188: if (required)
189: w.print(" #FIXED");
190: char lit = value.indexOf('"') < 0 ? '"' : '\'';
191: w.print(" " + lit + value + lit);
192: }
193: w.println(">");
194: }
195:
196: void writeExternalId(Entity entity) {
197: String pub = entity.getPublicId();
198: String sys = entity.getSystemId();
199: if (pub != null)
200: w.print("PUBLIC \"" + pub + "\"");
201: if (sys != null) {
202: if (pub == null)
203: w.print("SYSTEM");
204: w.print(' ');
205: char lit = sys.indexOf('\"') < 0 ? '"' : '\'';
206: w.print(lit);
207: w.print(sys);
208: w.print(lit);
209: }
210: }
211: }
|