001: /*
002: * (c) Copyright 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
003: * [See end of file]
004: */
005:
006: package com.hp.hpl.jena.rdf.arp.states;
007:
008: import java.util.Iterator;
009: import java.util.Map;
010: import java.util.TreeMap;
011:
012: import org.xml.sax.Attributes;
013: import org.xml.sax.SAXParseException;
014:
015: import com.hp.hpl.jena.rdf.arp.impl.AbsXMLContext;
016: import com.hp.hpl.jena.rdf.arp.impl.XMLHandler;
017:
018: public abstract class AbsXMLLiteral extends Frame {
019: boolean checkComposingChar = true;
020:
021: static Map xmlNameSpace = new TreeMap();
022: static {
023: xmlNameSpace.put("xml", xmlns);
024: xmlNameSpace.put("", "");
025: }
026:
027: String suggestParsetypeLiteral() {
028: // shouldn't be called.
029: return "";
030: }
031:
032: final protected StringBuffer rslt;
033: public final Map namespaces;
034:
035: private static String prefix(String qname) {
036: int colon = qname.indexOf(':');
037: return colon == -1 ? "" : qname.substring(0, colon);
038: }
039:
040: protected void append(String s) {
041: rslt.append(s);
042: }
043:
044: private void append(char ch[], int s, int l) {
045: rslt.append(ch, s, l);
046: }
047:
048: protected void append(char s) {
049: rslt.append(s);
050: }
051:
052: public AbsXMLLiteral(FrameI p, AbsXMLContext x, StringBuffer r) {
053: super (p, x);
054: rslt = r;
055: namespaces = xmlNameSpace;
056: }
057:
058: public AbsXMLLiteral(AbsXMLLiteral p, Map ns) {
059: super (p, p.xml);
060: rslt = p.rslt;
061: namespaces = ns;
062: }
063:
064: public AbsXMLLiteral(XMLHandler h, AbsXMLContext x) {
065: super (h, x);
066: rslt = new StringBuffer();
067: namespaces = xmlNameSpace;
068: }
069:
070: private void useNameSpace(String prefix, String uri, Map ns) {
071: if (!uri.equals(namespaces.get(prefix)))
072: ns.put(prefix, uri);
073: }
074:
075: abstract public void endElement() throws SAXParseException;
076:
077: void startLitElement(String uri, String rawName, Map ns) {
078: append('<');
079: append(rawName);
080: useNameSpace(prefix(rawName), uri, ns);
081: }
082:
083: private void appendAttrValue(String s) {
084: String replace;
085: char ch;
086: for (int i = 0; i < s.length(); i++) {
087: ch = s.charAt(i);
088: switch (ch) {
089: case '&':
090: replace = "&";
091: break;
092: case '<':
093: replace = "<";
094: break;
095: case '"':
096: replace = """;
097: break;
098: case 9:
099: replace = "	";
100: break;
101: case 0xA:
102: replace = "
";
103: break;
104: case 0xD:
105: replace = "
";
106: break;
107: default:
108: replace = null;
109: }
110: if (replace != null) {
111: append(replace);
112: } else {
113: append(ch);
114: }
115: }
116: }
117:
118: /** except all ampersands are replaced by &, all open angle
119: brackets () are replaced by <, all closing angle brackets
120: (>) are replaced by >, and all #xD characters are replaced
121: by 
.
122: * @throws SAXParseException
123: */
124: public void characters(char[] chrs, int start, int length)
125: throws SAXParseException {
126:
127: if (checkComposingChar)
128: checkComposingChar(taint, chrs, start, length);
129: checkComposingChar = false;
130:
131: String replace;
132: char ch;
133: for (int i = 0; i < length; i++) {
134: ch = chrs[start + i];
135: switch (ch) {
136: case '&':
137: replace = "&";
138: break;
139: case '<':
140: replace = "<";
141: break;
142: case '>':
143: replace = ">";
144: break;
145: case 0xD:
146: replace = "
";
147: break;
148: default:
149: replace = null;
150: }
151: if (replace != null) {
152: append(replace);
153: } else {
154: append(ch);
155: }
156: }
157: }
158:
159: public void comment(char[] ch, int start, int length)
160: throws SAXParseException {
161: append("<!--");
162: append(ch, start, length);
163: append("-->");
164:
165: checkComposingChar = true;
166: }
167:
168: public void processingInstruction(String target, String data) {
169: append("<?");
170: append(target);
171: append(' ');
172: append(data);
173: append("?>");
174:
175: checkComposingChar = true;
176: }
177:
178: public FrameI startElement(String uri, String localName,
179: String rawName, Attributes atts) {
180:
181: checkComposingChar = true;
182:
183: Map attrMap = new TreeMap();
184: Map childNameSpaces = new TreeMap();
185: startLitElement(uri, rawName, childNameSpaces);
186: for (int i = atts.getLength() - 1; i >= 0; i--) {
187: String ns = atts.getURI(i);
188: String qname = atts.getQName(i);
189: String prefix = prefix(qname);
190: if (!prefix.equals(""))
191: useNameSpace(prefix, ns, childNameSpaces);
192: attrMap.put(qname, atts.getValue(i));
193: }
194: // At this stage, childNameSpaces contains the new visibly used
195: // namespaces (i.e. those not in this).
196: // attrMap contains the attributes
197: // Both are sorted correctly, so we just read them off,
198: // namespaces first.
199: Iterator it = childNameSpaces.entrySet().iterator();
200: while (it.hasNext()) {
201: Map.Entry pair = (Map.Entry) it.next();
202: append(" xmlns");
203: String prefix = (String) pair.getKey();
204: if (!"".equals(prefix)) {
205: append(':');
206: append(prefix);
207: }
208: append("=\"");
209: appendAttrValue((String) pair.getValue());
210: append('"');
211: }
212: it = attrMap.entrySet().iterator();
213: while (it.hasNext()) {
214: Map.Entry pair = (Map.Entry) it.next();
215: append(' ');
216: append((String) pair.getKey());
217: append("=\"");
218: appendAttrValue((String) pair.getValue());
219: append('"');
220: }
221: append('>');
222:
223: // Now sort out our namespaces, so that
224: // child can see all of them.
225: if (childNameSpaces.isEmpty()) {
226: childNameSpaces = namespaces;
227: } else {
228: it = namespaces.entrySet().iterator();
229: while (it.hasNext()) {
230: Map.Entry pair = (Map.Entry) it.next();
231: String prefix = (String) pair.getKey();
232: if (!childNameSpaces.containsKey(prefix))
233: childNameSpaces.put(prefix, pair.getValue());
234: // else prefix was overwritten with different value
235: }
236: }
237: return new InnerXMLLiteral(this , rawName, childNameSpaces);
238: }
239:
240: }
241:
242: /*
243: * (c) Copyright 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
244: * All rights reserved.
245: *
246: * Redistribution and use in source and binary forms, with or without
247: * modification, are permitted provided that the following conditions
248: * are met:
249: * 1. Redistributions of source code must retain the above copyright
250: * notice, this list of conditions and the following disclaimer.
251: * 2. Redistributions in binary form must reproduce the above copyright
252: * notice, this list of conditions and the following disclaimer in the
253: * documentation and/or other materials provided with the distribution.
254: * 3. The name of the author may not be used to endorse or promote products
255: * derived from this software without specific prior written permission.
256: *
257: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
258: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
259: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
260: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
261: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
262: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
263: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
264: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
265: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
266: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
267: */
|