1 11 package org.eclipse.jface.text.templates.persistence; 12 13 import java.io.IOException ; 14 import java.io.InputStream ; 15 import java.io.OutputStream ; 16 import java.io.Reader ; 17 import java.io.Writer ; 18 import java.util.ArrayList ; 19 import java.util.Collection ; 20 import java.util.HashSet ; 21 import java.util.MissingResourceException ; 22 import java.util.ResourceBundle ; 23 import java.util.Set ; 24 25 import javax.xml.parsers.DocumentBuilder ; 26 import javax.xml.parsers.DocumentBuilderFactory ; 27 import javax.xml.parsers.ParserConfigurationException ; 28 import javax.xml.transform.OutputKeys ; 29 import javax.xml.transform.Transformer ; 30 import javax.xml.transform.TransformerException ; 31 import javax.xml.transform.TransformerFactory ; 32 import javax.xml.transform.dom.DOMSource ; 33 import javax.xml.transform.stream.StreamResult ; 34 35 import org.w3c.dom.Attr ; 36 import org.w3c.dom.Document ; 37 import org.w3c.dom.NamedNodeMap ; 38 import org.w3c.dom.Node ; 39 import org.w3c.dom.NodeList ; 40 import org.w3c.dom.Text ; 41 42 import org.eclipse.core.runtime.Assert; 43 44 import org.xml.sax.InputSource ; 45 import org.xml.sax.SAXException ; 46 47 import org.eclipse.jface.text.templates.Template; 48 49 58 public class TemplateReaderWriter { 59 60 private static final String TEMPLATE_ROOT = "templates"; private static final String TEMPLATE_ELEMENT = "template"; private static final String NAME_ATTRIBUTE= "name"; private static final String ID_ATTRIBUTE= "id"; private static final String DESCRIPTION_ATTRIBUTE= "description"; private static final String CONTEXT_ATTRIBUTE= "context"; private static final String ENABLED_ATTRIBUTE= "enabled"; private static final String DELETED_ATTRIBUTE= "deleted"; 71 private static final String AUTO_INSERTABLE_ATTRIBUTE= "autoinsert"; 73 76 public TemplateReaderWriter() { 77 } 78 79 87 public TemplatePersistenceData[] read(Reader reader) throws IOException { 88 return read(reader, null); 89 } 90 91 103 public TemplatePersistenceData readSingle(Reader reader, String id) throws IOException { 104 TemplatePersistenceData[] datas= read(new InputSource (reader), null, id); 105 if (datas.length > 0) 106 return datas[0]; 107 return null; 108 } 109 110 118 public TemplatePersistenceData[] read(Reader reader, ResourceBundle bundle) throws IOException { 119 return read(new InputSource (reader), bundle, null); 120 } 121 122 130 public TemplatePersistenceData[] read(InputStream stream, ResourceBundle bundle) throws IOException { 131 return read(new InputSource (stream), bundle, null); 132 } 133 134 143 private TemplatePersistenceData[] read(InputSource source, ResourceBundle bundle, String singleId) throws IOException { 144 try { 145 Collection templates= new ArrayList (); 146 Set ids= new HashSet (); 147 148 DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance(); 149 DocumentBuilder parser= factory.newDocumentBuilder(); 150 Document document= parser.parse(source); 151 152 NodeList elements= document.getElementsByTagName(TEMPLATE_ELEMENT); 153 154 int count= elements.getLength(); 155 for (int i= 0; i != count; i++) { 156 Node node= elements.item(i); 157 NamedNodeMap attributes= node.getAttributes(); 158 159 if (attributes == null) 160 continue; 161 162 String id= getStringValue(attributes, ID_ATTRIBUTE, null); 163 if (id != null && ids.contains(id)) 164 throw new IOException (TemplatePersistenceMessages.getString("TemplateReaderWriter.duplicate.id")); 166 if (singleId != null && !singleId.equals(id)) 167 continue; 168 169 boolean deleted = getBooleanValue(attributes, DELETED_ATTRIBUTE, false); 170 171 String name= getStringValue(attributes, NAME_ATTRIBUTE); 172 name= translateString(name, bundle); 173 174 String description= getStringValue(attributes, DESCRIPTION_ATTRIBUTE, ""); description= translateString(description, bundle); 176 177 String context= getStringValue(attributes, CONTEXT_ATTRIBUTE); 178 179 if (name == null || context == null) 180 throw new IOException (TemplatePersistenceMessages.getString("TemplateReaderWriter.error.missing_attribute")); 182 boolean enabled = getBooleanValue(attributes, ENABLED_ATTRIBUTE, true); 183 boolean autoInsertable= getBooleanValue(attributes, AUTO_INSERTABLE_ATTRIBUTE, true); 184 185 StringBuffer buffer= new StringBuffer (); 186 NodeList children= node.getChildNodes(); 187 for (int j= 0; j != children.getLength(); j++) { 188 String value= children.item(j).getNodeValue(); 189 if (value != null) 190 buffer.append(value); 191 } 192 String pattern= buffer.toString(); 193 pattern= translateString(pattern, bundle); 194 195 Template template= new Template(name, description, context, pattern, autoInsertable); 196 TemplatePersistenceData data= new TemplatePersistenceData(template, enabled, id); 197 data.setDeleted(deleted); 198 199 templates.add(data); 200 201 if (singleId != null && singleId.equals(id)) 202 break; 203 } 204 205 return (TemplatePersistenceData[]) templates.toArray(new TemplatePersistenceData[templates.size()]); 206 207 } catch (ParserConfigurationException e) { 208 Assert.isTrue(false); 209 } catch (SAXException e) { 210 Throwable t= e.getCause(); 211 if (t instanceof IOException ) 212 throw (IOException ) t; 213 else if (t != null) 214 throw new IOException (t.getMessage()); 215 else 216 throw new IOException (e.getMessage()); 217 } 218 219 return null; } 221 222 229 public void save(TemplatePersistenceData[] templates, OutputStream stream) throws IOException { 230 save(templates, new StreamResult (stream)); 231 } 232 233 240 public void save(TemplatePersistenceData[] templates, Writer writer) throws IOException { 241 save(templates, new StreamResult (writer)); 242 } 243 244 251 private void save(TemplatePersistenceData[] templates, StreamResult result) throws IOException { 252 try { 253 DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance(); 254 DocumentBuilder builder= factory.newDocumentBuilder(); 255 Document document= builder.newDocument(); 256 257 Node root= document.createElement(TEMPLATE_ROOT); 258 document.appendChild(root); 259 260 for (int i= 0; i < templates.length; i++) { 261 TemplatePersistenceData data= templates[i]; 262 Template template= data.getTemplate(); 263 264 Node node= document.createElement(TEMPLATE_ELEMENT); 265 root.appendChild(node); 266 267 NamedNodeMap attributes= node.getAttributes(); 268 269 String id= data.getId(); 270 if (id != null) { 271 Attr idAttr= document.createAttribute(ID_ATTRIBUTE); 272 idAttr.setValue(id); 273 attributes.setNamedItem(idAttr); 274 } 275 276 if (template != null) { 277 Attr name= document.createAttribute(NAME_ATTRIBUTE); 278 name.setValue(template.getName()); 279 attributes.setNamedItem(name); 280 } 281 282 if (template != null) { 283 Attr description= document.createAttribute(DESCRIPTION_ATTRIBUTE); 284 description.setValue(template.getDescription()); 285 attributes.setNamedItem(description); 286 } 287 288 if (template != null) { 289 Attr context= document.createAttribute(CONTEXT_ATTRIBUTE); 290 context.setValue(template.getContextTypeId()); 291 attributes.setNamedItem(context); 292 } 293 294 Attr enabled= document.createAttribute(ENABLED_ATTRIBUTE); 295 enabled.setValue(data.isEnabled() ? Boolean.toString(true) : Boolean.toString(false)); 296 attributes.setNamedItem(enabled); 297 298 Attr deleted= document.createAttribute(DELETED_ATTRIBUTE); 299 deleted.setValue(data.isDeleted() ? Boolean.toString(true) : Boolean.toString(false)); 300 attributes.setNamedItem(deleted); 301 302 if (template != null) { 303 Attr autoInsertable= document.createAttribute(AUTO_INSERTABLE_ATTRIBUTE); 304 autoInsertable.setValue(template.isAutoInsertable() ? Boolean.toString(true) : Boolean.toString(false)); 305 attributes.setNamedItem(autoInsertable); 306 } 307 308 if (template != null) { 309 Text pattern= document.createTextNode(template.getPattern()); 310 node.appendChild(pattern); 311 } 312 } 313 314 315 Transformer transformer=TransformerFactory.newInstance().newTransformer(); 316 transformer.setOutputProperty(OutputKeys.METHOD, "xml"); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); DOMSource source = new DOMSource (document); 319 320 transformer.transform(source, result); 321 322 } catch (ParserConfigurationException e) { 323 Assert.isTrue(false); 324 } catch (TransformerException e) { 325 if (e.getException() instanceof IOException ) 326 throw (IOException ) e.getException(); 327 Assert.isTrue(false); 328 } 329 } 330 331 private boolean getBooleanValue(NamedNodeMap attributes, String attribute, boolean defaultValue) throws SAXException { 332 Node enabledNode= attributes.getNamedItem(attribute); 333 if (enabledNode == null) 334 return defaultValue; 335 else if (enabledNode.getNodeValue().equals(Boolean.toString(true))) 336 return true; 337 else if (enabledNode.getNodeValue().equals(Boolean.toString(false))) 338 return false; 339 else 340 throw new SAXException (TemplatePersistenceMessages.getString("TemplateReaderWriter.error.illegal_boolean_attribute")); } 342 343 private String getStringValue(NamedNodeMap attributes, String name) throws SAXException { 344 String val= getStringValue(attributes, name, null); 345 if (val == null) 346 throw new SAXException (TemplatePersistenceMessages.getString("TemplateReaderWriter.error.missing_attribute")); return val; 348 } 349 350 private String getStringValue(NamedNodeMap attributes, String name, String defaultValue) { 351 Node node= attributes.getNamedItem(name); 352 return node == null ? defaultValue : node.getNodeValue(); 353 } 354 355 private String translateString(String str, ResourceBundle bundle) { 356 if (bundle == null) 357 return str; 358 359 int idx= str.indexOf('%'); 360 if (idx == -1) { 361 return str; 362 } 363 StringBuffer buf= new StringBuffer (); 364 int k= 0; 365 while (idx != -1) { 366 buf.append(str.substring(k, idx)); 367 for (k= idx + 1; k < str.length() && !Character.isWhitespace(str.charAt(k)); k++) { 368 } 370 String key= str.substring(idx + 1, k); 371 buf.append(getBundleString(key, bundle)); 372 idx= str.indexOf('%', k); 373 } 374 buf.append(str.substring(k)); 375 return buf.toString(); 376 } 377 378 private String getBundleString(String key, ResourceBundle bundle) { 379 if (bundle != null) { 380 try { 381 return bundle.getString(key); 382 } catch (MissingResourceException e) { 383 return '!' + key + '!'; 384 } 385 } 386 return TemplatePersistenceMessages.getString(key); } 388 } 389 390 | Popular Tags |