1 17 package org.apache.geronimo.system.configuration; 18 19 import java.beans.PropertyEditor ; 20 import java.io.IOException ; 21 import java.io.PrintWriter ; 22 import java.io.StringWriter ; 23 import java.io.Serializable ; 24 import java.io.StringReader ; 25 import java.net.URI ; 26 import java.util.ArrayList ; 27 import java.util.Collections ; 28 import java.util.HashMap ; 29 import java.util.Iterator ; 30 import java.util.LinkedHashMap ; 31 import java.util.LinkedHashSet ; 32 import java.util.Map ; 33 import java.util.Set ; 34 35 import javax.xml.parsers.DocumentBuilderFactory ; 36 import javax.xml.parsers.DocumentBuilder ; 37 38 import org.apache.geronimo.common.propertyeditor.PropertyEditors; 39 import org.apache.geronimo.gbean.AbstractName; 40 import org.apache.geronimo.gbean.AbstractNameQuery; 41 import org.apache.geronimo.gbean.GAttributeInfo; 42 import org.apache.geronimo.gbean.GBeanData; 43 import org.apache.geronimo.gbean.GBeanInfo; 44 import org.apache.geronimo.gbean.ReferencePatterns; 45 import org.apache.geronimo.kernel.InvalidGBeanException; 46 import org.apache.geronimo.kernel.util.XmlUtil; 47 import org.apache.geronimo.kernel.repository.Artifact; 48 import org.apache.geronimo.util.EncryptionManager; 49 import org.w3c.dom.Element ; 50 import org.w3c.dom.Node ; 51 import org.w3c.dom.NodeList ; 52 import org.w3c.dom.Document ; 53 import org.xml.sax.InputSource ; 54 55 58 public class GBeanOverride implements Serializable { 59 private final Object name; 60 private boolean load; 61 private final Map attributes = new LinkedHashMap (); 62 private final Map references = new LinkedHashMap (); 63 private final ArrayList clearAttributes = new ArrayList (); 64 private final ArrayList nullAttributes = new ArrayList (); 65 private final ArrayList clearReferences = new ArrayList (); 66 private final String gbeanInfo; 67 68 public GBeanOverride(String name, boolean load) { 69 this.name = name; 70 this.load = load; 71 gbeanInfo = null; 72 } 73 74 public GBeanOverride(AbstractName name, boolean load) { 75 this.name = name; 76 this.load = load; 77 gbeanInfo = null; 78 } 79 80 public GBeanOverride(GBeanData gbeanData) throws InvalidAttributeException { 81 GBeanInfo gbeanInfo = gbeanData.getGBeanInfo(); 82 this.gbeanInfo = gbeanInfo.getSourceClass(); 83 if (this.gbeanInfo == null) { 84 throw new IllegalArgumentException ("GBeanInfo must have a source class set"); 85 } 86 name = gbeanData.getAbstractName(); 87 load = true; 88 89 for (Iterator iterator = gbeanData.getAttributes().entrySet().iterator(); iterator.hasNext();) { 91 Map.Entry entry = (Map.Entry ) iterator.next(); 92 String attributeName = (String ) entry.getKey(); 93 GAttributeInfo attributeInfo = gbeanInfo.getAttribute(attributeName); 94 if (attributeInfo == null) { 95 throw new InvalidAttributeException("No attribute: " + attributeName + " for gbean: " + gbeanData.getAbstractName()); 96 } 97 Object attributeValue = entry.getValue(); 98 setAttribute(attributeName, attributeValue, attributeInfo.getType()); 99 } 100 101 references.putAll(gbeanData.getReferences()); 103 } 104 105 public GBeanOverride(Element gbean) throws InvalidGBeanException { 106 String nameString = gbean.getAttribute("name"); 107 if (nameString.indexOf('?') > -1) { 108 name = new AbstractName(URI.create(nameString)); 109 } else { 110 name = nameString; 111 } 112 113 String gbeanInfoString = gbean.getAttribute("gbeanInfo"); 114 if (gbeanInfoString.length() > 0) { 115 gbeanInfo = gbeanInfoString; 116 } else { 117 gbeanInfo = null; 118 } 119 if (gbeanInfo != null && !(name instanceof AbstractName)) { 120 throw new InvalidGBeanException("A gbean element using the gbeanInfo attribute must be specified using a full AbstractName: name=" + nameString); 121 } 122 123 String loadString = gbean.getAttribute("load"); 124 load = !"false".equals(loadString); 125 126 NodeList attributes = gbean.getElementsByTagName("attribute"); 128 for (int a = 0; a < attributes.getLength(); a++) { 129 Element attribute = (Element ) attributes.item(a); 130 131 String attributeName = attribute.getAttribute("name"); 132 133 if (attribute.hasAttribute("value")) { 135 setAttribute(attributeName, (String ) EncryptionManager.decrypt(attribute.getAttribute("value"))); 136 continue; 137 } 138 139 if (attribute.hasAttribute("null")) { 141 String nullString = attribute.getAttribute("null"); 142 if (nullString.equals("true")) { 143 setNullAttribute(attributeName); 144 continue; 145 } 146 } 147 148 String rawAttribute = getContentsAsText(attribute); 149 if (rawAttribute.length() == 0) { 151 setClearAttribute(attributeName); 152 continue; 153 } 154 String attributeValue = (String ) EncryptionManager.decrypt(rawAttribute); 155 156 setAttribute(attributeName, attributeValue); 157 } 158 159 NodeList references = gbean.getElementsByTagName("reference"); 161 for (int r = 0; r < references.getLength(); r++) { 162 Element reference = (Element ) references.item(r); 163 164 String referenceName = reference.getAttribute("name"); 165 166 Set objectNamePatterns = new LinkedHashSet (); 167 NodeList patterns = reference.getElementsByTagName("pattern"); 168 169 if (patterns.getLength() == 0) { 172 setClearReference(referenceName); 173 continue; 174 } 175 176 for (int p = 0; p < patterns.getLength(); p++) { 177 Element pattern = (Element ) patterns.item(p); 178 if (pattern == null) 179 continue; 180 181 String groupId = getChildAsText(pattern, "groupId"); 182 String artifactId = getChildAsText(pattern, "artifactId"); 183 String version = getChildAsText(pattern, "version"); 184 String type = getChildAsText(pattern, "type"); 185 String module = getChildAsText(pattern, "module"); 186 String name = getChildAsText(pattern, "name"); 187 188 Artifact referenceArtifact = null; 189 if (artifactId != null) { 190 referenceArtifact = new Artifact(groupId, artifactId, version, type); 191 } 192 Map nameMap = new HashMap (); 193 if (module != null) { 194 nameMap.put("module", module); 195 } 196 if (name != null) { 197 nameMap.put("name", name); 198 } 199 AbstractNameQuery abstractNameQuery = new AbstractNameQuery(referenceArtifact, nameMap, Collections.EMPTY_SET); 200 objectNamePatterns.add(abstractNameQuery); 201 } 202 203 setReferencePatterns(referenceName, new ReferencePatterns(objectNamePatterns)); 204 } 205 } 206 207 private static String getChildAsText(Element element, String name) throws InvalidGBeanException { 208 NodeList children = element.getElementsByTagName(name); 209 if (children == null || children.getLength() == 0) { 210 return null; 211 } 212 if (children.getLength() > 1) { 213 throw new InvalidGBeanException("invalid name, too many parts named: " + name); 214 } 215 return getContentsAsText((Element ) children.item(0)); 216 } 217 218 private static String getContentsAsText(Element element) throws InvalidGBeanException { 219 String value = ""; 220 NodeList text = element.getChildNodes(); 221 for (int t = 0; t < text.getLength(); t++) { 222 Node n = text.item(t); 223 if (n.getNodeType() == Node.TEXT_NODE) { 224 value += n.getNodeValue(); 225 } else { 226 StringWriter sw = new StringWriter (); 227 PrintWriter pw = new PrintWriter (sw); 228 OutputFormat of = new OutputFormat(Method.XML, null, false); 229 of.setOmitXMLDeclaration(true); 230 XMLSerializer serializer = new XMLSerializer(pw, of); 231 try { 232 serializer.prepare(); 233 serializer.serializeNode(n); 234 value += sw.toString(); 235 } catch (IOException ioe) { 236 throw new InvalidGBeanException("Error serializing GBean element", ioe); 237 } 238 } 239 } 240 return value.trim(); 241 } 242 243 public Object getName() { 244 return name; 245 } 246 247 public String getGBeanInfo() { 248 return gbeanInfo; 249 } 250 251 public boolean isLoad() { 252 return load; 253 } 254 255 public void setLoad(boolean load) { 256 this.load = load; 257 } 258 259 public Map getAttributes() { 260 return attributes; 261 } 262 263 public String getAttribute(String attributeName) { 264 return (String ) attributes.get(attributeName); 265 } 266 267 public ArrayList getClearAttributes() { 268 return clearAttributes; 269 } 270 271 public ArrayList getNullAttributes() { 272 return nullAttributes; 273 } 274 275 public boolean getNullAttribute(String attributeName) { 276 return nullAttributes.contains(attributeName); 277 } 278 279 public boolean getClearAttribute(String attributeName) { 280 return clearAttributes.contains(attributeName); 281 } 282 283 public ArrayList getClearReferences() { 284 return clearReferences; 285 } 286 287 public boolean getClearReference(String referenceName) { 288 return clearReferences.contains(referenceName); 289 } 290 291 public void setClearAttribute(String attributeName) { 292 if (!clearAttributes.contains(attributeName)) 293 clearAttributes.add(attributeName); 294 } 295 296 public void setNullAttribute(String attributeName) { 297 if (!nullAttributes.contains(attributeName)) 298 nullAttributes.add(attributeName); 299 } 300 301 public void setClearReference(String referenceName) { 302 if (!clearReferences.contains(referenceName)) 303 clearReferences.add(referenceName); 304 } 305 306 public void setAttribute(String attributeName, Object attributeValue, String attributeType) throws InvalidAttributeException { 307 String stringValue = getAsText(attributeValue, attributeType); 308 attributes.put(attributeName, stringValue); 309 } 310 311 public void setAttribute(String attributeName, String attributeValue) { 312 attributes.put(attributeName, attributeValue); 313 } 314 315 public Map getReferences() { 316 return references; 317 } 318 319 public ReferencePatterns getReferencePatterns(String name) { 320 return (ReferencePatterns) references.get(name); 321 } 322 323 public void setReferencePatterns(String name, ReferencePatterns patterns) { 324 references.put(name, patterns); 325 } 326 327 332 public Element writeXml(Document doc, Element parent) { 333 String gbeanName; 334 if (name instanceof String ) { 335 gbeanName = (String ) name; 336 } else { 337 gbeanName = name.toString(); 338 } 339 340 Element gbean = doc.createElement("gbean"); 341 parent.appendChild(gbean); 342 gbean.setAttribute("name", gbeanName); 343 if (gbeanInfo != null) { 344 gbean.setAttribute("gbeanInfo", gbeanInfo); 345 } 346 if (!load) { 347 gbean.setAttribute("load", "false"); 348 } 349 350 for (Iterator iterator = attributes.entrySet().iterator(); iterator.hasNext();) { 352 Map.Entry entry = (Map.Entry ) iterator.next(); 353 String name = (String ) entry.getKey(); 354 String value = (String ) entry.getValue(); 355 if (value == null) { 356 setNullAttribute(name); 357 } 358 else { 359 if (getNullAttribute(name)) { 360 nullAttributes.remove(name); 361 } 362 if (name.toLowerCase().indexOf("password") > -1) { 363 value = EncryptionManager.encrypt(value); 364 } 365 Element attribute = doc.createElement("attribute"); 366 attribute.setAttribute("name", name); 367 gbean.appendChild(attribute); 368 if (value.length() == 0) { 369 attribute.setAttribute("value", ""); 370 } 371 else { 372 try { 373 379 DocumentBuilderFactory factory = XmlUtil.newDocumentBuilderFactory(); 380 DocumentBuilder builder = factory.newDocumentBuilder(); 381 382 String xml = "<fragment>" + value + "</fragment>"; 384 InputSource input = new InputSource (new StringReader (xml)); 385 Document fragment = builder.parse(input); 386 387 Node root = fragment.getFirstChild(); 388 NodeList children = root.getChildNodes(); 389 for (int i=0; i<children.getLength(); i++) { 390 Node child = children.item(i); 391 392 child = doc.importNode(child, true); 394 attribute.appendChild(child); 395 } 396 } 397 catch (Exception e) { 398 throw new RuntimeException ("Failed to write attribute value fragment: " + e.getMessage(), e); 399 } 400 } 401 } 402 } 403 404 for (Iterator iterator = clearAttributes.iterator(); iterator.hasNext();) { 406 String name = (String ) iterator.next(); 407 Element attribute = doc.createElement("attribute"); 408 gbean.appendChild(attribute); 409 attribute.setAttribute("name", name); 410 } 411 412 for (Iterator iterator = nullAttributes.iterator(); iterator.hasNext();) { 414 String name = (String ) iterator.next(); 415 Element attribute = doc.createElement("attribute"); 416 gbean.appendChild(attribute); 417 attribute.setAttribute("name", name); 418 attribute.setAttribute("null", "true"); 419 } 420 421 for (Iterator iterator = references.entrySet().iterator(); iterator.hasNext();) { 423 Map.Entry entry = (Map.Entry ) iterator.next(); 424 String name = (String ) entry.getKey(); 425 ReferencePatterns patterns = (ReferencePatterns) entry.getValue(); 426 427 Element reference = doc.createElement("reference"); 428 reference.setAttribute("name", name); 429 gbean.appendChild(reference); 430 431 Set patternSet; 432 if (patterns.isResolved()) { 433 patternSet = Collections.singleton(new AbstractNameQuery(patterns.getAbstractName())); 434 } else { 435 patternSet = patterns.getPatterns(); 436 } 437 438 for (Iterator patternIterator = patternSet.iterator(); patternIterator.hasNext();) { 439 AbstractNameQuery pattern = (AbstractNameQuery) patternIterator.next(); 440 Element pat = doc.createElement("pattern"); 441 reference.appendChild(pat); 442 Artifact artifact = pattern.getArtifact(); 443 444 if (artifact != null) { 445 if (artifact.getGroupId() != null) { 446 Element group = doc.createElement("groupId"); 447 group.appendChild(doc.createTextNode(artifact.getGroupId())); 448 pat.appendChild(group); 449 } 450 if (artifact.getArtifactId() != null) { 451 Element art = doc.createElement("artifactId"); 452 art.appendChild(doc.createTextNode(artifact.getArtifactId())); 453 pat.appendChild(art); 454 } 455 if (artifact.getVersion() != null) { 456 Element version = doc.createElement("version"); 457 version.appendChild(doc.createTextNode(artifact.getVersion().toString())); 458 pat.appendChild(version); 459 } 460 if (artifact.getType() != null) { 461 Element type = doc.createElement("type"); 462 type.appendChild(doc.createTextNode(artifact.getType())); 463 pat.appendChild(type); 464 } 465 } 466 467 Map nameMap = pattern.getName(); 468 if (nameMap.get("module") != null) { 469 Element module = doc.createElement("module"); 470 module.appendChild(doc.createTextNode(nameMap.get("module").toString())); 471 pat.appendChild(module); 472 } 473 474 if (nameMap.get("name") != null) { 475 Element patName = doc.createElement("name"); 476 patName.appendChild(doc.createTextNode(nameMap.get("name").toString())); 477 pat.appendChild(patName); 478 } 479 } 480 } 481 482 for (Iterator iterator = clearReferences.iterator(); iterator.hasNext();) { 484 String name = (String ) iterator.next(); 485 Element reference = doc.createElement("reference"); 486 reference.setAttribute("name", name); 487 gbean.appendChild(reference); 488 } 489 490 return gbean; 491 } 492 493 public static String getAsText(Object value, String type) throws InvalidAttributeException { 494 try { 495 String attributeStringValue = null; 496 if (value != null) { 497 PropertyEditor editor = PropertyEditors.findEditor(type, GBeanOverride.class.getClassLoader()); 498 if (editor == null) { 499 throw new InvalidAttributeException("Unable to format attribute of type " + type + "; no editor found"); 500 } 501 editor.setValue(value); 502 attributeStringValue = editor.getAsText(); 503 } 504 return attributeStringValue; 505 } catch (ClassNotFoundException e) { 506 throw new InvalidAttributeException("Unable to store attribute type " + type); 508 } 509 } 510 } 511 | Popular Tags |