1 5 6 package org.exoplatform.services.jcr.impl.storage.rdb.container; 7 8 import java.util.*; 9 10 import javax.jcr.*; 11 12 import javax.jcr.query.Query; 13 import javax.jcr.query.QueryResult; 14 15 import net.sf.hibernate.Session; 16 import net.sf.hibernate.type.LongType; 17 import net.sf.hibernate.type.StringType; 18 19 import org.apache.commons.logging.Log; 20 import org.exoplatform.container.PortalContainer; 21 import org.exoplatform.services.jcr.core.ItemLocation; 22 import org.exoplatform.services.jcr.core.NodeData; 23 import org.exoplatform.services.jcr.impl.core.NodeImpl; 24 import org.exoplatform.services.jcr.impl.core.PropertyImpl; 25 import org.exoplatform.services.jcr.storage.WorkspaceContainer; 27 import org.exoplatform.services.log.LogUtil; 30 31 import org.exoplatform.services.jcr.impl.storage.rdb.container.data.*; 32 import org.exoplatform.services.database.HibernateServiceContainer; 34 import org.exoplatform.services.database.HibernateService; 35 36 38 39 40 45 public class RDBWorkspaceContainerImpl implements WorkspaceContainer { 46 47 static private String [] MAPPINGS = 48 { 49 "org/exoplatform/services/jcr/impl/storage/rdb/container/data/ValueRecord.hbm.xml" , 50 "org/exoplatform/services/jcr/impl/storage/rdb/container/data/PropertyRecord.hbm.xml", 51 "org/exoplatform/services/jcr/impl/storage/rdb/container/data/NodeRecord.hbm.xml", 52 } ; 53 54 55 private static String FIND_NODE = "from NodeRecord as node where node.path=?"; 56 private static String FIND_CHILDREN = "from NodeRecord as node where node.parentId=?"; 57 58 private static boolean initialized = false; 59 60 private Log log; 62 private String name; 63 private Long rootId; 64 private HibernateService hibernateService; 65 66 public RDBWorkspaceContainerImpl(String name, String dsName, String rootNodeType) throws RepositoryException { 67 68 log = LogUtil.getLog("org.exoplatform.services.jcr"); 69 70 this.name = name; 71 72 try { 73 74 75 HibernateServiceContainer hibernateContainer = (HibernateServiceContainer)PortalContainer. 76 getInstance().getComponentInstanceOfType(HibernateServiceContainer.class); 77 78 log.debug("RDBWorkspacecontainerImpl (String name, String dsName, String rootNodeType) hibernate container ="+hibernateContainer); 79 80 this.hibernateService = hibernateContainer.getHibernateService(dsName); 81 82 hibernateService.addMappingFiles(MAPPINGS); 83 84 init(name, rootNodeType); 85 86 } catch (Exception e) { 87 e.printStackTrace(); 88 throw new RepositoryException("RDBWorkspaceContainerImpl() failed Reason: "+e); 89 } 90 91 } 92 93 public RDBWorkspaceContainerImpl(String name, String dsName) throws RepositoryException { 94 this(name, dsName, "nt:default"); 95 } 96 97 private void init(String name, String rootNodeType) throws RepositoryException { 98 99 List nodes; 100 Session hibernateSession; 101 try { 102 hibernateSession = hibernateService.openSession(); 103 nodes = hibernateSession.find(FIND_NODE, ROOT_PATH, new StringType()); 104 } catch (Exception e) { 105 throw new RepositoryException("Hibernate failed: " + e); 106 } 107 108 if (nodes.isEmpty()) { 109 NodeRecord nodeRecord = new NodeRecord(); 110 nodeRecord.setPath(ROOT_PATH); 111 nodeRecord.setParentId(new Long (0l)); 112 HashSet rootProps = new HashSet(); 113 PropertyImpl rootProp = new PropertyImpl("/jcr:primaryType", 114 new StringValue(rootNodeType), PropertyType.STRING); 115 PropertyRecord rootPropRecord = getPropertyRecord(rootProp); 116 rootProps.add(rootPropRecord); 117 nodeRecord.setProperties(rootProps); 118 try { 119 rootId = (Long )hibernateSession.save(nodeRecord); 121 hibernateSession.save(rootPropRecord); 122 hibernateSession.save((StringValueRecord)rootPropRecord.getValues().iterator().next()); 123 hibernateSession.flush(); 124 } catch (Exception e) { 125 throw new RepositoryException("Hibernate failed: " + e); 126 } 127 log.debug("RDB ContainerImpl(), created root node " + rootId); 128 } else { 129 rootId = ((NodeRecord)nodes.get(0)).getId(); 130 } 131 132 } 133 134 public String getName() { 135 return name; 136 } 137 138 public NodeData getRootNode() throws RepositoryException { 139 return getNodeByPath(ROOT_PATH); 140 } 141 142 public NodeData getNodeByPath(String absPath) throws RepositoryException { 143 log.debug("RDB Container looks up node : " + absPath + " in workspace container: " + name); 144 try { 145 Session hibernateSession = hibernateService.openSession(); 146 List nodes = hibernateSession.find(FIND_NODE, absPath, new StringType()); 147 if (nodes.isEmpty()) 148 return null; 149 NodeRecord nodeRecord = (NodeRecord)nodes.get(0); 150 List properties = new ArrayList(); 151 Iterator props = nodeRecord.getProperties().iterator(); 152 while (props.hasNext()) { 153 PropertyRecord propertyRecord = (PropertyRecord)props.next(); 154 properties.add(getProperty(nodeRecord.getPath() + "/" + propertyRecord.getName(), propertyRecord)); 155 } 156 return new NodeImpl(nodeRecord.getPath(), properties); 157 } catch (Exception e) { 158 throw new RepositoryException("RDB Container.getNodeByPath() failed: <" + absPath + "> " + e.getMessage()); 159 } 160 } 161 162 public List getChildren(String path) throws RepositoryException { 163 try { 164 Session hibernateSession = hibernateService.openSession(); 165 List childrenPaths = new ArrayList(); 166 List nodes = hibernateSession.find(FIND_NODE, path, new StringType()); 167 if (nodes.isEmpty()) 168 return childrenPaths; 169 Long parentId = ((NodeRecord)nodes.get(0)).getId(); 170 List children = hibernateSession.find(FIND_CHILDREN, parentId, new LongType()); 171 for (int i = 0; i < children.size(); i++) { 172 NodeRecord nodeRecord = (NodeRecord)children.get(i); 173 childrenPaths.add(nodeRecord.getPath()); 174 } 175 return childrenPaths; 176 } catch (Exception e) { 177 e.printStackTrace(); 178 throw new RepositoryException("RDB Container.getChildren() failed: " + e.getMessage()); 179 } 180 } 181 182 public QueryResult getQueryResult(Query query) { 183 return null; 184 } 185 186 synchronized public void add(Node node) throws RepositoryException, ItemExistsException { 187 if (node.getPath().equals("/")) 188 return; 189 log.debug("RDB Container is adding " + node + " to workspace container: " + name); 190 try { 191 Session hibernateSession = hibernateService.openSession(); 192 String parentPath = new ItemLocation(node.getPath()).getParentPath(); 193 List parentNodes = hibernateSession.find(FIND_NODE, parentPath, new StringType()); 194 if (parentNodes.isEmpty()) { 195 log.warn("RDBContainer add() failed. Parent for " + node.getPath() + " not found. NodesModificationManager should proccess this!"); 196 return; 197 } 198 Long parentId = ((NodeRecord)parentNodes.get(0)).getId(); 200 NodeImpl nodeImpl = (NodeImpl)node; 201 202 NodeRecord nodeRecord = new NodeRecord(); 203 nodeRecord.setPath(node.getPath()); 204 nodeRecord.setParentId(parentId); 205 hibernateSession.save(nodeRecord); 206 207 List props = nodeImpl.getPermanentProperties(); 208 Set propertyRecords = new HashSet(); 209 for (int i = 0; i < props.size(); i++) { 210 PropertyImpl prop = (PropertyImpl)props.get(i); 211 PropertyRecord propertyRecord = getPropertyRecord(prop); 212 213 propertyRecords.add(propertyRecord); 214 hibernateSession.save(propertyRecord); 215 216 Iterator valueRecords = propertyRecord.getValues().iterator(); 217 while(valueRecords.hasNext()) { 218 hibernateSession.save((ValueRecord) valueRecords.next()); 219 } 220 } 221 222 nodeRecord.setProperties(propertyRecords); 223 hibernateSession.update(nodeRecord); 224 225 hibernateSession.flush(); 226 } catch (Exception e) { 227 e.printStackTrace(); 228 throw new RepositoryException("RDB Container.add() failed: " + e.getMessage()); 229 } 230 log.debug("RDB Container added " + node + " to workspace container: " + name); 231 } 232 233 synchronized public void delete(String absPath) throws RepositoryException { 234 try { 235 Session hibernateSession = hibernateService.openSession(); 236 hibernateSession.delete(FIND_NODE, absPath, new StringType()); 237 } catch (Exception e) { 239 throw new RepositoryException("RDB Container.delete() failed: " + e.getMessage()); 240 } 241 log.debug("RDB Container removed " + absPath); 242 } 243 244 synchronized public void update(Node node) throws RepositoryException { 245 try { 246 Session hibernateSession = hibernateService.openSession(); 247 List nodes = hibernateSession.find(FIND_NODE, node.getPath(), new StringType()); 248 if (nodes.isEmpty()) 249 throw new RepositoryException("RDB Container could not find node for update " + node); 250 NodeRecord nodeRecord = (NodeRecord)nodes.get(0); 251 NodeImpl nodeImpl = (NodeImpl)node; 252 List props = nodeImpl.getPermanentProperties(); 253 Set propertyRecords = new HashSet(); 254 for (int i = 0; i < props.size(); i++) { 255 PropertyImpl prop = (PropertyImpl)props.get(i); 256 propertyRecords.add(getPropertyRecord(prop)); 257 } 258 nodeRecord.setProperties(propertyRecords); 259 hibernateSession.update(nodeRecord); 260 hibernateSession.flush(); 261 } catch (Exception e) { 262 throw new RepositoryException("RDB Container.update() failed: " + e.getMessage()); 263 } 264 log.debug("RDB Container updated " + node); 265 } 266 267 private PropertyImpl getProperty(String path, PropertyRecord propertyRecord) throws RepositoryException, ValueFormatException { 268 Value[] values = new Value[propertyRecord.getValues().size()]; 269 Iterator valueRecords = propertyRecord.getValues().iterator(); 270 int i = 0; 271 while (valueRecords.hasNext()) { 272 ValueRecord valueRecord = (ValueRecord)valueRecords.next(); 273 if (valueRecord instanceof StringValueRecord) 274 values[i++] = new StringValue(((StringValueRecord)valueRecord).getValue()); 275 else if (valueRecord instanceof DateValueRecord) 276 values[i++] = new DateValue(((DateValueRecord)valueRecord).getValue()); 277 else if (valueRecord instanceof BooleanValueRecord) 278 values[i++] = new BooleanValue(((BooleanValueRecord)valueRecord).getValue()); 279 else if (valueRecord instanceof LongValueRecord) 280 values[i++] = new LongValue(((LongValueRecord)valueRecord).getValue()); 281 else if (valueRecord instanceof DoubleValueRecord) 282 values[i++] = new DoubleValue(((DoubleValueRecord)valueRecord).getValue()); 283 else if (valueRecord instanceof ReferenceValueRecord) 284 values[i++] = new ReferenceValue(((ReferenceValueRecord)valueRecord).getValue()); 285 else if (valueRecord instanceof SoftLinkValueRecord) 286 values[i++] = new SoftLinkValue(((SoftLinkValueRecord)valueRecord).getValue()); 287 else if (valueRecord instanceof BinaryValueRecord) 288 values[i++] = new BinaryValue(((BinaryValueRecord)valueRecord).getValue()); 289 else 290 throw new ValueFormatException("Unknown Value record " + valueRecord.getClass()); 291 } 292 return new PropertyImpl(path, values, values[0].getType()); 293 } 294 295 private PropertyRecord getPropertyRecord(PropertyImpl property) throws RepositoryException, ValueFormatException { 296 Value[] values = property.getValues(); 297 Set valueRecords = new HashSet(); 298 for (int i = 0; i < values.length; i++) { 299 if (values[i] instanceof StringValue) { 300 try { 301 valueRecords.add(new StringValueRecord(values[i].getString())); 302 } catch (ValueFormatException e) { 303 log.warn("RDBWorkspaceContainerImpl.getPropertyRecord() -- Value format exception for "+property+" Presume NULL value."); 304 valueRecords.add(new StringValueRecord()); 305 } 306 } else if (values[i] instanceof DateValue) { 307 try{ 308 valueRecords.add(new DateValueRecord(values[i].getDate())); 309 } catch (ValueFormatException e) { 310 log.warn("RDBWorkspaceContainerImpl.getPropertyRecord() -- Value format exception for "+property+" Presume NULL value."); 311 valueRecords.add(new DateValueRecord()); 312 } 313 } else if (values[i] instanceof BooleanValue) { 314 try { 315 valueRecords.add(new BooleanValueRecord(new Boolean (values[i].getBoolean()))); 316 } catch (ValueFormatException e) { 317 log.warn("RDBWorkspaceContainerImpl.getPropertyRecord() -- Value format exception for "+property+" Presume NULL value."); 318 valueRecords.add(new BooleanValueRecord()); 319 } 320 } else if (values[i] instanceof LongValue) { 321 try { 322 valueRecords.add(new LongValueRecord(new Long (values[i].getLong()))); 323 } catch (ValueFormatException e) { 324 log.warn("RDBWorkspaceContainerImpl.getPropertyRecord() -- Value format exception for "+property+" Presume NULL value."); 325 valueRecords.add(new StringValueRecord()); 326 } 327 } else if (values[i] instanceof DoubleValue) { 328 try { 329 valueRecords.add(new DoubleValueRecord(new Double (values[i].getDouble()))); 330 } catch (ValueFormatException e) { 331 log.warn("RDBWorkspaceContainerImpl.getPropertyRecord() -- Value format exception for "+property+" Presume NULL value."); 332 valueRecords.add(new DoubleValueRecord()); 333 } 334 } else if (values[i] instanceof ReferenceValue) { 335 try { 336 valueRecords.add(new ReferenceValueRecord(values[i].getString())); 337 } catch (ValueFormatException e) { 338 log.warn("RDBWorkspaceContainerImpl.getPropertyRecord() -- Value format exception for "+property+" Presume NULL value."); 339 valueRecords.add(new ReferenceValueRecord()); 340 } 341 } else if (values[i] instanceof SoftLinkValue) { 342 try { 343 valueRecords.add(new SoftLinkValueRecord(values[i].getString())); 344 } catch (ValueFormatException e) { 345 log.warn("RDBWorkspaceContainerImpl.getPropertyRecord() -- Value format exception for "+property+" Presume NULL value."); 346 valueRecords.add(new SoftLinkValueRecord()); 347 } 348 } else if (values[i] instanceof BinaryValue) { 349 try { 350 valueRecords.add(new BinaryValueRecord(values[i].getString().getBytes())); 351 } catch (ValueFormatException e) { 352 log.warn("RDBWorkspaceContainerImpl.getPropertyRecord() -- Value format exception for "+property+" Presume NULL value."); 353 valueRecords.add(new BinaryValueRecord()); 354 } 355 } else 356 throw new ValueFormatException("Unknown Value record for " + property); 358 } 359 PropertyRecord propertyRecord = new PropertyRecord(); 360 propertyRecord.setName(property.getName()); 361 propertyRecord.setValues(valueRecords); 362 return propertyRecord; 363 } 364 } 365 | Popular Tags |