001 /* 002 * Copyright 2006 Stephen J. McConnell. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.lang; 020 021 import dpml.util.ElementHelper; 022 023 import java.io.File; 024 import java.io.IOException; 025 import java.net.URI; 026 import java.net.URL; 027 028 import net.dpml.transit.Artifact; 029 030 import org.w3c.dom.Document; 031 import org.w3c.dom.Element; 032 import org.w3c.dom.NamedNodeMap; 033 import org.w3c.dom.Node; 034 035 /** 036 * Exception related to data decoding from a DOM element. 037 */ 038 public class DecodingException extends IOException 039 { 040 private final Element m_element; 041 042 /** 043 * Create a new decoding exception. 044 * @param element the element representing the source of the error 045 * @param message the exception message 046 */ 047 public DecodingException( String message, Element element ) 048 { 049 this( message, null, element ); 050 } 051 052 /** 053 * Create a new decoding exception. 054 * @param element the element representing the source of the error 055 * @param message the exception message 056 * @param cause the causal exception 057 */ 058 public DecodingException( String message, Throwable cause, Element element ) 059 { 060 super( message ); 061 if( null != cause ) 062 { 063 super.initCause( cause ); 064 } 065 m_element = element; 066 } 067 068 /** 069 * Get the element that is the subject of this exception. 070 * @return the subject element 071 */ 072 public Element getElement() 073 { 074 return m_element; 075 } 076 077 /** 078 * Return a string representation of the exception. 079 * @return the string value 080 */ 081 public String getMessage() 082 { 083 try 084 { 085 String message = super.getMessage(); 086 StringBuffer buffer = new StringBuffer( message ); 087 Element element = getElement(); 088 if( null != element ) 089 { 090 Document document = element.getOwnerDocument(); 091 String uri = document.getDocumentURI(); 092 if( null != uri ) 093 { 094 buffer.append( "\nSource: " + uri ); 095 String filename = getSourceFilePath( uri ); 096 if( null != filename ) 097 { 098 buffer.append( "\nFile: " + filename ); 099 } 100 buffer.append( "\n" ); 101 } 102 String listing = list( element ); 103 buffer.append( listing ); 104 } 105 return buffer.toString(); 106 } 107 catch( Throwable e ) 108 { 109 return super.getMessage(); 110 } 111 } 112 113 /** 114 * Static utility operation that returns a string representation of a DOM element. 115 * @param element the element to stringify 116 * @return the string value 117 */ 118 public static String list( Element element ) 119 { 120 return list( element, "" ); 121 } 122 123 /** 124 * Static utility operation that returns a syring representation of a DOM element. 125 * @param element the element to stringify 126 * @param pad padding offset 127 * @return the string value 128 */ 129 public static String list( Element element, String pad ) 130 { 131 if( null == element ) 132 { 133 return ""; 134 } 135 StringBuffer buffer = new StringBuffer(); 136 String tag = element.getTagName(); 137 buffer.append( pad + "<" ); 138 buffer.append( tag ); 139 NamedNodeMap map = element.getAttributes(); 140 for( int i=0; i<map.getLength(); i++ ) 141 { 142 Node item = map.item( i ); 143 buffer.append( " " + item.getNodeName() + "=\"" ); 144 buffer.append( item.getNodeValue() ); 145 buffer.append( "\"" ); 146 } 147 148 Element[] children = ElementHelper.getChildren( element ); 149 if( children.length > 0 ) 150 { 151 buffer.append( ">" ); 152 for( int i=0; i<children.length; i++ ) 153 { 154 Element child = children[i]; 155 String listing = list( child, pad + " " ); 156 String tagName = child.getTagName(); 157 buffer.append( "\n" + listing ); 158 } 159 buffer.append( "\n" + pad + "</" + tag + ">" ); 160 } 161 else 162 { 163 buffer.append( "/>" ); 164 } 165 return buffer.toString(); 166 } 167 168 private static String getSourceFilePath( String value ) 169 { 170 try 171 { 172 URI uri = URI.create( value ); 173 if( Artifact.isRecognized( uri ) ) 174 { 175 URL url = Artifact.toURL( uri ); 176 File file = (File) url.getContent( new Class[]{File.class} ); 177 return file.getCanonicalPath(); 178 } 179 return null; 180 } 181 catch( Throwable e ) 182 { 183 return null; 184 } 185 } 186 187 }