/* * Copyright 2004-2015 the Seasar Foundation and the Others. * * 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 * * 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 org.seasar.framework.xml; import java.io.InputStream; import java.net.URL; import java.util.HashMap; import java.util.Map; import org.seasar.framework.util.ResourceUtil; import org.seasar.framework.util.URLUtil; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; /** * SAXのイベントを処理するためのクラスです。 * * @author higa * */ public class SaxHandler extends DefaultHandler { private TagHandlerRule tagHandlerRule; private TagHandlerContext context = new TagHandlerContext(); private Map dtdPaths = new HashMap(); private Locator locator; /** * {@link SaxHandler}を作成します。 * * @param tagHandlerRule */ public SaxHandler(TagHandlerRule tagHandlerRule) { this.tagHandlerRule = tagHandlerRule; } /** * {@link TagHandlerContext}を返します。 * * @return {@link TagHandlerContext} */ public TagHandlerContext getTagHandlerContext() { return context; } public void setDocumentLocator(Locator locator) { this.locator = locator; } public void startDocument() throws SAXException { context.setLocator(locator); } public void startElement(String namespaceURI, String localName, String qName, Attributes attributes) { appendBody(); context.startElement(qName); start(attributes); } public void characters(char[] buffer, int start, int length) { int begin = start; int end = start + length; for (int i = begin; i < end; ++i) { if (buffer[i] == '\n') { context.characters(buffer, begin, i - begin + 1); appendBody(); begin = i + 1; } } if (begin < end) { context.characters(buffer, begin, end - begin); } } public void endElement(String namespaceURI, String localName, String qName) { appendBody(); end(); context.endElement(); } public InputSource resolveEntity(String publicId, String systemId) throws SAXException { if (publicId != null) { String dtdPath = (String) dtdPaths.get(publicId); if (dtdPath != null) { return createInputSource(ResourceUtil .getResourceAsStream(dtdPath), systemId); } } if (systemId == null) { return null; } if (systemId.startsWith("file:")) { URL url = URLUtil.create(systemId); String path = url.getFile(); if (path.startsWith("/")) { path = path.substring(1); } return createInputSource(ResourceUtil.getResourceAsStream(path), systemId); } return new InputSource(ResourceUtil.getResourceAsStream(systemId)); } public void error(SAXParseException e) throws SAXException { throw e; } public void warning(SAXParseException e) throws SAXException { System.err.println(e); } /** * DTDの実際のパスを登録します。 * * @param publicId * @param dtdPath */ public void registerDtdPath(String publicId, String dtdPath) { dtdPaths.put(publicId, dtdPath); } /** * 処理された結果を返します。 * * @return 処理された結果 */ public Object getResult() { return context.getResult(); } private InputSource createInputSource(InputStream stream, String systemId) { InputSource is = new InputSource(stream); is.setSystemId(systemId); return is; } private TagHandler getTagHandlerByPath() { return tagHandlerRule.getTagHandler(context.getPath()); } private TagHandler getTagHandlerByQName() { return tagHandlerRule.getTagHandler(context.getQName()); } private void start(Attributes attributes) { TagHandler th = getTagHandlerByPath(); start(th, attributes); th = getTagHandlerByQName(); start(th, attributes); } private void start(TagHandler handler, Attributes attributes) { if (handler != null) { try { handler.start(context, attributes); } catch (RuntimeException ex) { reportDetailPath(); ex.printStackTrace(); throw ex; } } } private void appendBody() { String characters = context.getCharacters(); if (characters.length() > 0) { TagHandler th = getTagHandlerByPath(); appendBody(th, characters); th = getTagHandlerByQName(); appendBody(th, characters); context.clearCharacters(); } } private void appendBody(TagHandler handler, String characters) { if (handler != null) { try { handler.appendBody(context, characters); } catch (RuntimeException ex) { reportDetailPath(); ex.printStackTrace(); throw ex; } } } private void end() { String body = context.getBody(); TagHandler th = getTagHandlerByPath(); end(th, body); th = getTagHandlerByQName(); end(th, body); } private void end(TagHandler handler, String body) { if (handler != null) { try { handler.end(context, body); } catch (RuntimeException ex) { reportDetailPath(); ex.printStackTrace(); throw ex; } } } private void reportDetailPath() { System.err.println("Exception occured at " + context.getDetailPath()); } }