1 47 package com.lowagie.text.pdf; 48 49 import java.io.BufferedWriter ; 50 import java.io.IOException ; 51 import java.io.InputStream ; 52 import java.io.OutputStream ; 53 import java.io.OutputStreamWriter ; 54 import java.io.Reader ; 55 import java.io.Writer ; 56 import java.util.ArrayList ; 57 import java.util.HashMap ; 58 import java.util.Iterator ; 59 import java.util.Map ; 60 import java.util.StringTokenizer ; 61 62 import com.lowagie.text.xml.simpleparser.IanaEncodings; 63 import com.lowagie.text.xml.simpleparser.SimpleXMLDocHandler; 64 import com.lowagie.text.xml.simpleparser.SimpleXMLParser; 65 66 70 public class SimpleNamedDestination implements SimpleXMLDocHandler { 71 72 private HashMap xmlNames; 73 private HashMap xmlLast; 74 75 private SimpleNamedDestination() { 76 } 77 78 public static HashMap getNamedDestination(PdfReader reader, boolean fromNames) { 79 IntHashtable pages = new IntHashtable(); 80 int numPages = reader.getNumberOfPages(); 81 for (int k = 1; k <= numPages; ++k) 82 pages.put(reader.getPageOrigRef(k).getNumber(), k); 83 HashMap names = fromNames ? reader.getNamedDestinationFromNames() : reader.getNamedDestinationFromStrings(); 84 for (Iterator it = names.entrySet().iterator(); it.hasNext();) { 85 Map.Entry entry = (Map.Entry )it.next(); 86 ArrayList arr = ((PdfArray)entry.getValue()).getArrayList(); 87 StringBuffer s = new StringBuffer (); 88 try { 89 s.append(pages.get(((PdfIndirectReference)arr.get(0)).getNumber())); 90 s.append(' ').append(arr.get(1).toString().substring(1)); 91 for (int k = 2; k < arr.size(); ++k) 92 s.append(' ').append(arr.get(k).toString()); 93 entry.setValue(s.toString()); 94 } 95 catch (Exception e) { 96 it.remove(); 97 } 98 } 99 return names; 100 } 101 102 120 public static void exportToXML(HashMap names, OutputStream out, String encoding, boolean onlyASCII) throws IOException { 121 String jenc = IanaEncodings.getJavaEncoding(encoding); 122 Writer wrt = new BufferedWriter (new OutputStreamWriter (out, jenc)); 123 exportToXML(names, wrt, encoding, onlyASCII); 124 } 125 126 135 public static void exportToXML(HashMap names, Writer wrt, String encoding, boolean onlyASCII) throws IOException { 136 wrt.write("<?xml version=\"1.0\" encoding=\""); 137 wrt.write(SimpleXMLParser.escapeXML(encoding, onlyASCII)); 138 wrt.write("\"?>\n<Destination>\n"); 139 for (Iterator it = names.entrySet().iterator(); it.hasNext();) { 140 Map.Entry entry = (Map.Entry )it.next(); 141 String key = (String )entry.getKey(); 142 String value = (String )entry.getValue(); 143 wrt.write(" <Name Page=\""); 144 wrt.write(SimpleXMLParser.escapeXML(value, onlyASCII)); 145 wrt.write("\">"); 146 wrt.write(SimpleXMLParser.escapeXML(escapeBinaryString(key), onlyASCII)); 147 wrt.write("</Name>\n"); 148 } 149 wrt.write("</Destination>\n"); 150 wrt.flush(); 151 } 152 153 159 public static HashMap importFromXML(InputStream in) throws IOException { 160 SimpleNamedDestination names = new SimpleNamedDestination(); 161 SimpleXMLParser.parse(names, in); 162 return names.xmlNames; 163 } 164 165 171 public static HashMap importFromXML(Reader in) throws IOException { 172 SimpleNamedDestination names = new SimpleNamedDestination(); 173 SimpleXMLParser.parse(names, in); 174 return names.xmlNames; 175 } 176 177 static PdfArray createDestinationArray(String value, PdfWriter writer) { 178 PdfArray ar = new PdfArray(); 179 StringTokenizer tk = new StringTokenizer (value); 180 int n = Integer.parseInt(tk.nextToken()); 181 ar.add(writer.getPageReference(n)); 182 if (!tk.hasMoreTokens()) { 183 ar.add(PdfName.XYZ); 184 ar.add(new float[]{0, 10000, 0}); 185 } 186 else { 187 String fn = tk.nextToken(); 188 if (fn.startsWith("/")) 189 fn = fn.substring(1); 190 ar.add(new PdfName(fn)); 191 for (int k = 0; k < 4 && tk.hasMoreTokens(); ++k) { 192 fn = tk.nextToken(); 193 if (fn.equals("null")) 194 ar.add(PdfNull.PDFNULL); 195 else 196 ar.add(new PdfNumber(fn)); 197 } 198 } 199 return ar; 200 } 201 202 public static PdfDictionary outputNamedDestinationAsNames(HashMap names, PdfWriter writer) { 203 PdfDictionary dic = new PdfDictionary(); 204 for (Iterator it = names.entrySet().iterator(); it.hasNext();) { 205 Map.Entry entry = (Map.Entry )it.next(); 206 try { 207 String key = (String )entry.getKey(); 208 String value = (String )entry.getValue(); 209 PdfArray ar = createDestinationArray(value, writer); 210 PdfName kn = new PdfName(key); 211 dic.put(kn, ar); 212 } 213 catch (Exception e) { 214 } 216 } 217 return dic; 218 } 219 220 public static PdfDictionary outputNamedDestinationAsStrings(HashMap names, PdfWriter writer) throws IOException { 221 HashMap n2 = new HashMap (names); 222 for (Iterator it = n2.entrySet().iterator(); it.hasNext();) { 223 Map.Entry entry = (Map.Entry )it.next(); 224 try { 225 String value = (String )entry.getValue(); 226 PdfArray ar = createDestinationArray(value, writer); 227 entry.setValue(writer.addToBody(ar).getIndirectReference()); 228 } 229 catch (Exception e) { 230 it.remove(); 231 } 232 } 233 return PdfNameTree.writeTree(n2, writer); 234 } 235 236 public static String escapeBinaryString(String s) { 237 StringBuffer buf = new StringBuffer (); 238 char cc[] = s.toCharArray(); 239 int len = cc.length; 240 for (int k = 0; k < len; ++k) { 241 char c = cc[k]; 242 if (c < ' ') { 243 buf.append('\\'); 244 String octal = "00" + Integer.toOctalString((int)c); 245 buf.append(octal.substring(octal.length() - 3)); 246 } 247 else if (c == '\\') 248 buf.append("\\\\"); 249 else 250 buf.append(c); 251 } 252 return buf.toString(); 253 } 254 255 public static String unEscapeBinaryString(String s) { 256 StringBuffer buf = new StringBuffer (); 257 char cc[] = s.toCharArray(); 258 int len = cc.length; 259 for (int k = 0; k < len; ++k) { 260 char c = cc[k]; 261 if (c == '\\') { 262 if (++k >= len) { 263 buf.append('\\'); 264 break; 265 } 266 c = cc[k]; 267 if (c >= '0' && c <= '7') { 268 int n = c - '0'; 269 ++k; 270 for (int j = 0; j < 2 && k < len; ++j) { 271 c = cc[k]; 272 if (c >= '0' && c <= '7') { 273 ++k; 274 n = n * 8 + c - '0'; 275 } 276 else { 277 break; 278 } 279 } 280 --k; 281 buf.append((char)n); 282 } 283 else 284 buf.append(c); 285 } 286 else 287 buf.append(c); 288 } 289 return buf.toString(); 290 } 291 292 public void endDocument() { 293 } 294 295 public void endElement(String tag) { 296 if (tag.equals("Destination")) { 297 if (xmlLast == null && xmlNames != null) 298 return; 299 else 300 throw new RuntimeException ("Destination end tag out of place."); 301 } 302 if (!tag.equals("Name")) 303 throw new RuntimeException ("Invalid end tag - " + tag); 304 if (xmlLast == null || xmlNames == null) 305 throw new RuntimeException ("Name end tag out of place."); 306 if (!xmlLast.containsKey("Page")) 307 throw new RuntimeException ("Page attribute missing."); 308 xmlNames.put(unEscapeBinaryString((String )xmlLast.get("Name")), xmlLast.get("Page")); 309 xmlLast = null; 310 } 311 312 public void startDocument() { 313 } 314 315 public void startElement(String tag, HashMap h) { 316 if (xmlNames == null) { 317 if (tag.equals("Destination")) { 318 xmlNames = new HashMap (); 319 return; 320 } 321 else 322 throw new RuntimeException ("Root element is not Destination."); 323 } 324 if (!tag.equals("Name")) 325 throw new RuntimeException ("Tag " + tag + " not allowed."); 326 if (xmlLast != null) 327 throw new RuntimeException ("Nested tags are not allowed."); 328 xmlLast = new HashMap (h); 329 xmlLast.put("Name", ""); 330 } 331 332 public void text(String str) { 333 if (xmlLast == null) 334 return; 335 String name = (String )xmlLast.get("Name"); 336 name += str; 337 xmlLast.put("Name", name); 338 } 339 } | Popular Tags |