1 9 package org.jboss.portal.core.impl.tree.loader; 10 11 import org.jboss.cache.loader.CacheLoader; 12 import org.jboss.cache.TreeCache; 13 import org.jboss.cache.Fqn; 14 import org.jboss.cache.Modification; 15 import org.jboss.portal.cms.CMS; 16 import org.jboss.portal.cms.NodeFactory; 17 import org.jboss.portal.cms.Node; 18 import org.jboss.portal.cms.Content; 19 import org.jboss.portal.cms.NoSuchURIException; 20 import org.jboss.portal.common.transaction.Transactions; 21 import org.jboss.portal.core.impl.tree.Property; 22 import org.apache.log4j.Logger; 23 24 import java.util.Properties ; 25 import java.util.Set ; 26 import java.util.Map ; 27 import java.util.List ; 28 import java.util.Iterator ; 29 import java.util.HashSet ; 30 import java.util.HashMap ; 31 import java.util.ArrayList ; 32 import java.io.ObjectStreamException ; 33 import java.io.ByteArrayOutputStream ; 34 import java.io.ObjectOutputStream ; 35 import java.io.IOException ; 36 import java.io.ByteArrayInputStream ; 37 import java.io.ObjectInputStream ; 38 import java.io.DataOutputStream ; 39 import java.io.DataInputStream ; 40 41 45 public class CMSCacheLoader implements CacheLoader 46 { 47 48 49 protected Logger log = Logger.getLogger(CMSCacheLoader.class); 50 51 52 protected Properties props; 53 54 55 protected TreeCache cache; 56 57 58 protected String path; 59 60 61 protected Map transactions; 62 63 64 protected CMS cms; 65 66 67 protected Map marshallers = new HashMap (); 68 69 public CMSCacheLoader() 70 { 71 transactions = new HashMap (); 72 } 73 74 public void setConfig(Properties props) 75 { 76 this.props = props; 77 this.path = props.getProperty("cache.cms.path", "/scheme"); 78 for (Iterator i = props.keySet().iterator();i.hasNext();) 79 { 80 String propName = (String )i.next(); 81 if (propName.startsWith("cache.cms.marshaller.")) 82 { 83 String marshallerClassName = props.getProperty(propName); 84 String className = propName.substring("cache.cms.marshaller.".length()); 85 log.debug("Associate class " + className + " with marshaller class " + marshallerClassName); 86 try 87 { 88 Class marshallerClass = (Class )Thread.currentThread().getContextClassLoader().loadClass(marshallerClassName); 89 ContentMarshaller marshaller = (ContentMarshaller)marshallerClass.newInstance(); 90 marshallers.put(className, marshaller); 91 } 92 catch (ClassNotFoundException e) 93 { 94 log.error("Cannot load marshaller class" + marshallerClassName, e); 95 } 96 catch (InstantiationException e) 97 { 98 log.error("Cannot create marshaller instance " + marshallerClassName, e); 99 } 100 catch (IllegalAccessException e) 101 { 102 log.error("Cannot create marshaller instance " + marshallerClassName, e); 103 } 104 } 105 } 106 107 } 108 109 public void setCache(TreeCache cache) 110 { 111 this.cache = cache; 112 } 113 114 public Set getChildrenNames(final Fqn fqn) throws Exception 115 { 116 return (Set )Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable() 117 { 118 public Object run() throws Exception 119 { 120 String uri = toURI(fqn); 121 Set names = null; 122 Node node = getFactory().getNode(uri); 123 if (node.exists()) 124 { 125 for (Iterator i = node.getChildren().values().iterator(); i.hasNext();) 126 { 127 Node child = (Node)i.next(); 128 try 129 { 130 if (child.isDir()) 131 { 132 if (names == null) 133 { 134 names = new HashSet (); 135 } 136 names.add(child.getName()); 137 } 138 } 139 catch (NullPointerException e) 140 { 141 e.printStackTrace(); 142 throw (NullPointerException )e; 143 } 144 } 145 } 146 return names; 147 } 148 }); 149 } 150 151 public Object get(final Fqn fqn, final Object key) throws Exception 152 { 153 return Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable() 154 { 155 public Object run() throws Exception 156 { 157 String uri = toURI(fqn); 158 Node node = getFactory().getNode(uri); 159 Node child = node.getChild(key.toString()); 160 if (child.exists()) 161 { 162 Object o = loadContent(child); 163 return o; 164 } 165 else 166 { 167 return null; 168 } 169 } 170 }); 171 } 172 173 public Map get(final Fqn fqn) throws Exception 174 { 175 return (Map )Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable() 176 { 177 public Object run() throws Exception 178 { 179 String uri = toURI(fqn); 180 Node node = getFactory().getNode(uri); 181 Map data = null; 182 if (node.exists()) 183 { 184 Map children = node.getChildren(); 185 if (children.size() > 0) 186 { 187 for (Iterator i = children.values().iterator(); i.hasNext();) 188 { 189 Node child = (Node)i.next(); 190 if (!child.isDir()) 191 { 192 if (data == null) 193 { 194 data = new HashMap (); 195 } 196 Object o = loadContent(child); 197 data.put(child.getName(), o); 198 } 199 } 200 } 201 } 202 return data; 203 } 204 }); 205 } 206 207 public boolean exists(final Fqn fqn) throws Exception 208 { 209 Boolean exists = (Boolean )Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable() 210 { 211 public Object run() throws Exception 212 { 213 String uri = toURI(fqn); 214 Node node = getFactory().getNode(uri); 215 boolean exists = node.exists(); 216 return Boolean.valueOf(exists); 217 } 218 }); 219 return exists.booleanValue(); 220 } 221 222 public Object put(final Fqn fqn, final Object key, final Object value) throws Exception 223 { 224 return Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable() 225 { 226 public Object run() throws Exception 227 { 228 String uri = toURI(fqn); 229 Node node = getFactory().getNode(uri); 230 Node child = node.getChild(key.toString()); 231 if (child.exists()) 232 { 233 Object o = loadContent(child); 234 storeContent(child, (Property)value); 235 return o; 236 } 237 else 238 { 239 storeContent(child, (Property)value); 240 return null; 241 } 242 } 243 }); 244 } 245 246 public void put(Fqn fqn, Map data) throws Exception 247 { 248 put(fqn, data, false); 249 } 250 251 public void put(final Fqn fqn, final Map data, final boolean erase) throws Exception 252 { 253 Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable() 254 { 255 public Object run() throws Exception 256 { 257 String uri = toURI(fqn); 258 Node node = getFactory().getNode(uri); 259 node.createDir(true); 260 if (erase) 261 { 262 for (Iterator i = node.getChildren().values().iterator(); i.hasNext();) 263 { 264 Node child = (Node)i.next(); 265 if (!child.isDir()) 266 { 267 child.delete(); 268 } 269 } 270 } 271 if (data != null) 272 { 273 for (Iterator i = data.entrySet().iterator(); i.hasNext();) 274 { 275 Map.Entry entry = (Map.Entry )i.next(); 276 String key = entry.getKey().toString(); 277 Object value = entry.getValue(); 278 Node child = getFactory().getNode(uri + "/" + key); 279 storeContent(child, (Property)value); 280 } 281 } 282 return null; 283 } 284 }); 285 } 286 287 public Object remove(final Fqn fqn, final Object key) throws Exception 288 { 289 return Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable() 290 { 291 public Object run() throws Exception 292 { 293 String uri = toURI(fqn); 294 Node node = getFactory().getNode(uri); 295 Node child = node.getChild(key.toString()); 296 if (child.exists()) 297 { 298 Object value = loadContent(child); 299 child.delete(); 300 return value; 301 } 302 else 303 { 304 return null; 305 } 306 } 307 }); 308 } 309 310 public void remove(final Fqn fqn) throws Exception 311 { 312 Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable() 313 { 314 public Object run() throws Exception 315 { 316 String uri = toURI(fqn); 317 Node node = getFactory().getNode(uri); 318 try 319 { 320 node.delete(); 321 } 322 catch (NoSuchURIException e) 323 { 324 } 326 return null; 327 } 328 }); 329 } 330 331 public void removeData(final Fqn fqn) throws Exception 332 { 333 Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable() 334 { 335 public Object run() throws Exception 336 { 337 String uri = toURI(fqn); 338 Node node = getFactory().getNode(uri); 339 Map children = node.getChildren(); 340 for (Iterator i = children.values().iterator(); i.hasNext();) 341 { 342 Node child = (Node)i.next(); 343 if (!child.isDir()) 344 { 345 child.delete(); 346 } 347 } 348 return null; 349 } 350 }); 351 } 352 353 public void put(final List modifications) throws Exception 354 { 355 Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable() 356 { 357 public Object run() throws Exception 358 { 359 for (Iterator it = modifications.iterator(); it.hasNext();) 360 { 361 Modification m = (Modification)it.next(); 362 switch (m.getType()) 363 { 364 case Modification.PUT_DATA: 365 put(m.getFqn(), m.getData()); 366 break; 367 case Modification.PUT_DATA_ERASE: 368 put(m.getFqn(), m.getData(), true); 369 break; 370 case Modification.PUT_KEY_VALUE: 371 put(m.getFqn(), m.getKey(), m.getValue()); 372 break; 373 case Modification.REMOVE_DATA: 374 removeData(m.getFqn()); 375 break; 376 case Modification.REMOVE_KEY_VALUE: 377 remove(m.getFqn(), m.getKey()); 378 break; 379 case Modification.REMOVE_NODE: 380 remove(m.getFqn()); 381 break; 382 default: 383 log.error("modification type " + m.getType() + " not known"); 384 break; 385 } 386 } 387 return null; 388 } 389 }); 390 } 391 392 public void prepare(Object tx, List modifications, boolean onePhase) throws Exception 393 { 394 if (onePhase) 395 { 396 put(modifications); 397 } 398 else 399 { 400 transactions.put(tx, modifications); 401 } 402 } 403 404 public void commit(Object tx) throws Exception 405 { 406 final List modifications = (List )transactions.get(tx); 407 Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable() 408 { 409 public Object run() throws Exception 410 { 411 put(modifications); 412 return null; 413 } 414 }); 415 } 416 417 public void rollback(Object tx) 418 { 419 transactions.remove(tx); 420 } 421 422 public byte[] loadEntireState() throws Exception 423 { 424 return (byte[])Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable() 425 { 426 public Object run() throws Exception 427 { 428 String uri = toURI(new Fqn()); 429 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 430 DataOutputStream dos = new DataOutputStream (baos); 431 loadState(uri, dos); 432 dos.close(); 433 byte[] bytes = baos.toByteArray(); 434 return bytes; 435 } 436 }); 437 } 438 439 public void storeEntireState(final byte[] state) throws Exception 440 { 441 Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable() 442 { 443 public Object run() throws Exception 444 { 445 ByteArrayInputStream bais = new ByteArrayInputStream (state); 446 DataInputStream dis = new DataInputStream (bais); 447 storeState(dis); 448 return null; 449 } 450 }); 451 } 452 453 456 public void create() throws Exception 457 { 458 cms = CMS.getCMS(); 459 } 460 461 public void start() throws Exception 462 { 463 464 } 465 466 public void stop() 467 { 468 469 } 470 471 public void destroy() 472 { 473 } 474 475 481 protected void loadState(String uri, final DataOutputStream out) throws Exception 482 { 483 Node node = getFactory().getNode(uri); 485 if (node.exists()) 486 { 487 Map children = node.getChildren(); 488 List contentNodes = new ArrayList (); 489 List dirNodes = new ArrayList (); 490 for (Iterator i = children.values().iterator(); i.hasNext();) 491 { 492 Node child = (Node)i.next(); 493 if (child.isDir()) 494 { 495 dirNodes.add(child); 496 } 497 else 498 { 499 contentNodes.add(child); 500 } 501 } 502 503 out.writeUTF(uri); 505 506 out.writeInt(contentNodes.size()); 508 for (int i = 0; i < contentNodes.size(); i++) 509 { 510 Node contentNode = (Node)contentNodes.get(i); 511 Content content = contentNode.getContent(); 512 out.writeUTF(contentNode.getURI()); 513 out.writeUTF(content.getMimeType()); 514 byte[] bytes = content.getBytes(); 515 out.writeInt(bytes.length); 516 out.write(bytes); 517 } 518 519 out.writeInt(dirNodes.size()); 521 for (int i = 0; i < dirNodes.size(); i++) 522 { 523 Node dirNode = (Node)dirNodes.get(i); 524 loadState(dirNode.getURI(), out); 525 } 526 } 527 } 528 529 534 protected void storeState(final DataInputStream in) throws Exception 535 { 536 String uri = in.readUTF(); 537 Node node = getFactory().getNode(uri); 538 node.createDir(true); 539 540 for (int contentSize = in.readInt(); contentSize > 0; contentSize--) 542 { 543 String contentURI = in.readUTF(); 544 String contentType = in.readUTF(); 545 int length = in.readInt(); 546 byte[] bytes = new byte[length]; 547 in.read(bytes, 0, length); 548 Node contentNode = getFactory().getNode(contentURI); 549 contentNode.createContent(new Content(bytes, contentType), true); 550 } 551 552 for (int dirSize = in.readInt(); dirSize > 0; dirSize--) 554 { 555 storeState(in); 556 } 557 } 558 559 565 protected String toURI(Fqn fqn) 566 { 567 StringBuffer buffer = new StringBuffer (path); 568 for (int i = 0; i < fqn.size(); i++) 569 { 570 buffer.append("/").append(fqn.get(i)); 571 } 572 return buffer.toString(); 573 } 574 575 585 protected Property loadContent(Node node) throws Exception 586 { 587 Content content = node.getContent(); 588 589 String className = node.getProperty("jboss", "classname"); 591 592 ContentMarshaller marshaller = (ContentMarshaller)marshallers.get(className); 594 595 Object value = null; 597 if (marshaller != null) 598 { 599 value = marshaller.unmarshall(content); 600 } 601 else 602 { 603 byte[] bytes = content.getBytes(); 604 value = defaultUnmarshall(bytes); 605 } 606 Property prop = new Property(node.getName(), value); 607 return prop; 608 } 609 610 620 protected void storeContent(Node node, Property prop) throws Exception 621 { 622 Object value = prop.getValue(); 623 String className = value.getClass().getName(); 624 625 Content content = null; 626 ContentMarshaller marshaller = (ContentMarshaller)marshallers.get(className); 627 if (marshaller != null) 628 { 629 content = marshaller.marshall(value); 630 } 631 else 632 { 633 byte[] bytes = defaultMarshall(value); 634 content = new Content(bytes, "text/plain"); 635 } 636 637 node.createContent(content, true); 638 node.setProperty("jboss", "classname", className); 639 } 640 641 648 protected byte[] defaultMarshall(Object o) throws ObjectStreamException 649 { 650 ByteArrayOutputStream baos = null; 651 try 652 { 653 baos = new ByteArrayOutputStream (); 654 ObjectOutputStream oos = new ObjectOutputStream (baos); 655 oos.writeObject(o); 656 oos.close(); 657 return baos.toByteArray(); 658 } 659 catch (IOException e) 660 { 661 if (e instanceof ObjectStreamException ) 662 { 663 throw (ObjectStreamException )e; 664 } 665 throw new Error ("Impossible", e); 666 } 667 } 668 669 678 protected Object defaultUnmarshall(byte[] bytes) throws ClassNotFoundException , ObjectStreamException 679 { 680 try 681 { 682 ByteArrayInputStream bais = new ByteArrayInputStream (bytes); 683 ObjectInputStream ois = new ObjectInputStream (bais); 684 return ois.readObject(); 685 } 686 catch (IOException e) 687 { 688 if (e instanceof ObjectStreamException ) 689 { 690 throw (ObjectStreamException )e; 691 } 692 throw new Error ("Impossible", e); 693 } 694 } 695 696 private NodeFactory getFactory() 697 { 698 return cms.getNodeFactory(); 699 } 700 } 701 | Popular Tags |