1 16 package org.apache.cocoon.jcr.source; 17 18 import java.io.IOException ; 19 import java.net.MalformedURLException ; 20 import java.util.HashMap ; 21 import java.util.Map ; 22 23 import javax.jcr.LoginException; 24 import javax.jcr.Node; 25 import javax.jcr.Property; 26 import javax.jcr.Repository; 27 import javax.jcr.RepositoryException; 28 import javax.jcr.Session; 29 30 import org.apache.avalon.framework.CascadingRuntimeException; 31 import org.apache.avalon.framework.configuration.Configurable; 32 import org.apache.avalon.framework.configuration.Configuration; 33 import org.apache.avalon.framework.configuration.ConfigurationException; 34 import org.apache.avalon.framework.service.ServiceException; 35 import org.apache.avalon.framework.service.ServiceManager; 36 import org.apache.avalon.framework.service.Serviceable; 37 import org.apache.avalon.framework.thread.ThreadSafe; 38 import org.apache.excalibur.source.Source; 39 import org.apache.excalibur.source.SourceException; 40 import org.apache.excalibur.source.SourceFactory; 41 import org.apache.excalibur.source.SourceUtil; 42 43 111 public class JCRSourceFactory implements ThreadSafe, SourceFactory, Configurable, Serviceable { 112 113 protected static class NodeTypeInfo { 114 } 116 117 protected static class FolderTypeInfo extends NodeTypeInfo { 118 public String newFileType; 119 120 public String newFolderType; 121 } 122 123 protected static class FileTypeInfo extends NodeTypeInfo { 124 public String contentPath; 125 126 public String contentType; 127 128 public String contentRef; 129 } 130 131 protected static class ContentTypeInfo extends NodeTypeInfo { 132 public String contentProp; 133 134 public String mimeTypeProp; 135 136 public String lastModifiedProp; 137 138 public String validityProp; 139 } 140 141 144 protected Repository repo; 145 146 149 protected String scheme; 150 151 154 protected Map typeInfos; 155 156 protected ServiceManager manager; 157 158 public void service(ServiceManager manager) throws ServiceException { 159 this.manager = manager; 160 } 163 164 public void configure(Configuration config) throws ConfigurationException { 165 this.typeInfos = new HashMap (); 166 167 Configuration[] children = config.getChildren(); 168 169 for (int i = 0; i < children.length; i++) { 170 Configuration child = children[i]; 171 String name = child.getName(); 172 173 if ("folder-node".equals(name)) { 174 FolderTypeInfo info = new FolderTypeInfo(); 175 String type = child.getAttribute("type"); 176 info.newFileType = child.getAttribute("new-file"); 177 info.newFolderType = child.getAttribute("new-folder", type); 178 179 this.typeInfos.put(type, info); 180 181 } else if ("file-node".equals(name)) { 182 FileTypeInfo info = new FileTypeInfo(); 183 info.contentPath = child.getAttribute("content-path", null); 184 info.contentType = child.getAttribute("content-type", null); 185 info.contentRef = child.getAttribute("content-ref", null); 186 if (info.contentPath == null && info.contentRef == null) { 187 throw new ConfigurationException("One of content-path or content-ref is required at " + child.getLocation()); 188 } 189 if (info.contentPath != null && info.contentType == null) { 190 throw new ConfigurationException("content-type must be present with content-path at " + child.getLocation()); 191 } 192 this.typeInfos.put(child.getAttribute("type"), info); 193 194 } else if ("content-node".equals(name)) { 195 ContentTypeInfo info = new ContentTypeInfo(); 196 info.contentProp = child.getAttribute("content-prop"); 197 info.lastModifiedProp = child.getAttribute("lastmodified-prop", null); 198 info.mimeTypeProp = child.getAttribute("mimetype-prop", null); 199 info.validityProp = child.getAttribute("validity-prop", info.lastModifiedProp); 200 this.typeInfos.put(child.getAttribute("type"), info); 201 202 } else { 203 throw new ConfigurationException("Unknown configuration " + name + " at " + child.getLocation()); 204 } 205 } 206 207 } 208 209 protected void lazyInit() { 210 if (this.repo == null) { 211 try { 212 this.repo = (Repository)manager.lookup(Repository.class.getName()); 213 } catch (Exception e) { 214 throw new CascadingRuntimeException("Cannot lookup repository", e); 215 } 216 } 217 } 218 219 225 public Source getSource(String uri, Map parameters) throws IOException , MalformedURLException { 226 lazyInit(); 227 228 if (this.scheme == null) { 229 this.scheme = SourceUtil.getScheme(uri); 230 } 231 232 Session session; 233 try { 234 session = repo.login(); 236 } catch (LoginException e) { 237 throw new SourceException("Login to repository failed", e); 238 } catch (RepositoryException e) { 239 throw new SourceException("Cannot access repository", e); 240 } 241 242 String path = SourceUtil.getSpecificPart(uri); 244 if (!path.startsWith("//")) { 245 throw new MalformedURLException ("Expecting " + this.scheme + "://path and got " + uri); 246 } 247 path = path.substring(1); 249 int pathLen = path.length(); 250 if (pathLen > 1) { 251 if (path.charAt(pathLen - 1) == '/') { 253 path = path.substring(0, pathLen - 1); 254 } 255 } 256 257 return createSource(session, path); 258 } 259 260 265 public void release(Source source) { 266 } 268 269 public String getScheme() { 270 return this.scheme; 271 } 272 273 280 public NodeTypeInfo getTypeInfo(Node node) throws RepositoryException { 281 String typeName = node.getPrimaryNodeType().getName(); 282 NodeTypeInfo result = (NodeTypeInfo) this.typeInfos.get(typeName); 283 if (result == null) { 284 throw new RepositoryException("No type info found for node type '" + typeName + "' at " + node.getPath()); 286 } 287 288 return result; 289 } 290 291 297 public NodeTypeInfo getTypeInfo(String typeName) throws RepositoryException { 298 NodeTypeInfo result = (NodeTypeInfo) this.typeInfos.get(typeName); 299 if (result == null) { 300 throw new RepositoryException("No type info found for node type '" + typeName + "'"); 302 } 303 304 return result; 305 } 306 307 314 public Node getContentNode(Node node) throws RepositoryException { 315 NodeTypeInfo info = getTypeInfo(node); 316 317 if (info instanceof ContentTypeInfo) { 318 return node; 319 320 } else if (info instanceof FileTypeInfo) { 321 FileTypeInfo finfo = (FileTypeInfo) info; 322 if (".".equals(finfo.contentPath)) { 323 return node; 324 } else if (finfo.contentPath != null) { 325 return node.getNode(finfo.contentPath); 326 } else { 327 Property ref = node.getProperty(finfo.contentRef); 328 return getContentNode(ref.getNode()); 329 } 330 } else { 331 throw new RepositoryException("Can't get content node for folder node at " + node.getPath()); 333 } 334 } 335 336 344 public JCRNodeSource createSource(JCRNodeSource parent, Node node) throws SourceException { 345 return new JCRNodeSource(parent, node); 346 } 347 348 356 public JCRNodeSource createSource(Session session, String path) throws SourceException { 357 return new JCRNodeSource(this, session, path); 358 } 359 360 368 public Node createFileNode(Node folderNode, String name) throws RepositoryException { 369 NodeTypeInfo info = getTypeInfo(folderNode); 370 if (!(info instanceof FolderTypeInfo)) { 371 throw new RepositoryException("Node type " + folderNode.getPrimaryNodeType().getName() + " is not a folder type"); 372 } 373 374 FolderTypeInfo folderInfo = (FolderTypeInfo) info; 375 return folderNode.addNode(name, folderInfo.newFileType); 376 } 377 378 385 public Node createContentNode(Node fileNode) throws RepositoryException { 386 387 NodeTypeInfo info = getTypeInfo(fileNode); 388 if (!(info instanceof FileTypeInfo)) { 389 throw new RepositoryException("Node type " + fileNode.getPrimaryNodeType().getName() + " is not a file type"); 390 } 391 392 FileTypeInfo fileInfo = (FileTypeInfo) info; 393 Node contentNode = fileNode.addNode(fileInfo.contentPath, fileInfo.contentType); 394 395 return contentNode; 396 } 397 398 405 public Property getContentProperty(Node node) throws RepositoryException { 406 Node contentNode = getContentNode(node); 407 ContentTypeInfo info = (ContentTypeInfo) getTypeInfo(contentNode); 408 return contentNode.getProperty(info.contentProp); 409 } 410 411 418 public Property getMimeTypeProperty(Node node) throws RepositoryException { 419 Node contentNode = getContentNode(node); 420 ContentTypeInfo info = (ContentTypeInfo) getTypeInfo(contentNode); 421 422 String propName = info.mimeTypeProp; 423 if (propName != null && contentNode.hasProperty(propName)) { 424 return contentNode.getProperty(propName); 425 } else { 426 return null; 427 } 428 } 429 430 437 public Property getLastModifiedDateProperty(Node node) throws RepositoryException { 438 Node contentNode = getContentNode(node); 439 ContentTypeInfo info = (ContentTypeInfo) getTypeInfo(contentNode); 440 441 String propName = info.lastModifiedProp; 442 if (propName != null && contentNode.hasProperty(propName)) { 443 return contentNode.getProperty(propName); 444 } else { 445 return null; 446 } 447 } 448 449 456 public Property getValidityProperty(Node node) throws RepositoryException { 457 Node contentNode = getContentNode(node); 458 ContentTypeInfo info = (ContentTypeInfo) getTypeInfo(contentNode); 459 460 String propName = info.validityProp; 461 if (propName != null && contentNode.hasProperty(propName)) { 462 return contentNode.getProperty(propName); 463 } else { 464 return null; 465 } 466 } 467 468 475 public boolean isCollection(Node node) throws RepositoryException { 476 return getTypeInfo(node) instanceof FolderTypeInfo; 477 } 478 479 486 public String getFolderNodeType(Node folderNode) throws RepositoryException { 487 FolderTypeInfo info = (FolderTypeInfo) getTypeInfo(folderNode); 488 return info.newFolderType; 489 } 490 } 491 | Popular Tags |