Return-Path: X-Original-To: apmail-jackrabbit-users-archive@minotaur.apache.org Delivered-To: apmail-jackrabbit-users-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 682979DE4 for ; Fri, 6 Apr 2012 11:38:46 +0000 (UTC) Received: (qmail 11703 invoked by uid 500); 6 Apr 2012 11:38:45 -0000 Delivered-To: apmail-jackrabbit-users-archive@jackrabbit.apache.org Received: (qmail 11675 invoked by uid 500); 6 Apr 2012 11:38:45 -0000 Mailing-List: contact users-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@jackrabbit.apache.org Delivered-To: mailing list users@jackrabbit.apache.org Received: (qmail 11659 invoked by uid 99); 6 Apr 2012 11:38:45 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 06 Apr 2012 11:38:45 +0000 X-ASF-Spam-Status: No, hits=2.8 required=5.0 tests=HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS,URI_HEX X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of fcarriedos@gmail.com designates 209.85.213.170 as permitted sender) Received: from [209.85.213.170] (HELO mail-yx0-f170.google.com) (209.85.213.170) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 06 Apr 2012 11:38:38 +0000 Received: by yenl5 with SMTP id l5so2338206yen.1 for ; Fri, 06 Apr 2012 04:38:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:reply-to:in-reply-to:references:from:date:message-id :subject:to:content-type; bh=JaBayZhnD+h1ffB+yw4vKONYohG9wsTLg3LidAdtqSo=; b=jxYA/K/n5WRXxIpuUIHyug7/OjCYTt4qyQE5KysgBJq4n0tpF7HlTwJJm5LQyxoOaz fYl3hiC4cEsCcGazsVK0GkLcTJYT1w4IDTWueyl2IA//aavx7y1oSWNKTGhMDqc4tr84 kDSg1i5fN7JnDjVACzKn9Uk2JIukjTgGfFNpMLXTNoWm3G3Sb/MK+i4Wt/WmiYuBEELU HKdXMAUKyIOSLFSHnlZonvVtPJaDveO2DiLyu3CkvzhyWHiFiysu3RO/7Nxy0OiwldM3 qN2tuPoPraI+C3XVdrToPNxdWlsd1Le12+FsHATKOx/e0iFnXzUP1AZ7NgxlM+e9P0rv G23A== Received: by 10.236.114.200 with SMTP id c48mr6801463yhh.23.1333712297406; Fri, 06 Apr 2012 04:38:17 -0700 (PDT) MIME-Version: 1.0 Received: by 10.101.13.20 with HTTP; Fri, 6 Apr 2012 04:37:56 -0700 (PDT) Reply-To: fcarriedos@gmail.com In-Reply-To: References: <8A9F81CB-49B7-414D-95F1-882C3A61A1ED@pooteeweet.org> <4F699D5D.9010001@liip.ch> From: Francisco Carriedo Scher Date: Fri, 6 Apr 2012 13:37:56 +0200 Message-ID: Subject: Re: Creating a nt:linkedFile To: users@jackrabbit.apache.org Content-Type: multipart/alternative; boundary=20cf303bfae6b82fc604bd0117f3 --20cf303bfae6b82fc604bd0117f3 Content-Type: text/plain; charset=ISO-8859-1 Hi there, i wrote a custom IOHandler to have the nt:linkedFile nodes retrieved as the file they link through the browser. I would like to offer it to anyone who faces the same problem so i post it here and i will put it as answer to the helpful link i found (see below). There are three code snippets: declaring the nt:linkedFile as noncollection on the config.xml file, the IOHandler Java class itself (the change needs to recompile the jackrabbit-jcr-server project) and the line to add in the config.xml file (within jackrabbit-webapp project, recompile it too) in order to use the brandnew IOHandler (order matters, put the declaration on the first position). Here it goes: ******************************************************************************************************************* Set the nt:linkedFile as noncollection (config.xml on jackrabbit-webapp): [...] nt:file *nt:linkedFile* nt:resource [...] ******************************************************************************************************************* LinkHandler.java (put it on *org.apache.jackrabbit.server.io.LinkHandler*package within the jackrabbit-jcr-server project). package org.apache.jackrabbit.server.io; import java.io.IOException; import javax.jcr.Item; import javax.jcr.Node; import javax.jcr.PathNotFoundException; import javax.jcr.Property; import javax.jcr.RepositoryException; import org.apache.jackrabbit.JcrConstants; import org.apache.jackrabbit.webdav.DavResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LinkHandler implements IOHandler { private static Logger log = LoggerFactory.getLogger(LinkHandler.class); private IOManager ioManager; public IOManager getIOManager() { return this.ioManager; } public void setIOManager(IOManager ioManager) { this.ioManager = ioManager; } public String getName() { return getClass().getName(); } public boolean canImport(ImportContext context, boolean isCollection) { // As we do not want this handler to manage the links on their income // because they are properly managed by the existing handlers return false; } public boolean canImport(ImportContext context, DavResource resource) { // As we do not want this handler to manage the links on their income // because they are properly managed by the existing handlers return false; } public boolean importContent(ImportContext context, boolean isCollection) throws IOException { // TODO Auto-generated method stub return false; } public boolean importContent(ImportContext context, DavResource resource) throws IOException { // TODO Auto-generated method stub return false; } public boolean canExport(ExportContext context, boolean isCollection) { // Error controlling i supose... if (context == null) return false; Item item; Node node; boolean itemIsNotNull; boolean isNode; boolean isLink; boolean result = false; item = context.getExportRoot(); node = (Node) item; itemIsNotNull = (item != null); isNode = (item.isNode()); try { // There is no content but a reference to content isLink = (node.getProperty("jcr:content") != null); // Everything right? Then true result = itemIsNotNull && isNode && isLink && (!isCollection); } catch (PathNotFoundException e) { e.printStackTrace(); } catch (RepositoryException e) { e.printStackTrace(); } return result; } public boolean canExport(ExportContext context, DavResource resource) { if (resource == null) { return false; } return canExport(context, resource.isCollection()); } public boolean exportContent(ExportContext context, boolean isCollection) throws IOException { if (!canExport(context,isCollection)) throw new IOException(getName() + ": Cannot export " + context.getExportRoot()); try { Node linkedFile = (Node) context.getExportRoot(); Node contentNode = linkedFile.getProperty("jcr:content").getNode(); System.out.println("LinkedFile: " + linkedFile.getName()); if (context.hasStream()) { exportData(context,isCollection, contentNode); } return true; } catch (RepositoryException e) { } return false; } public boolean exportContent(ExportContext context, DavResource resource) throws IOException { if (!canExport(context, resource)) { throw new IOException(getName() + ": Cannot export " + context.getExportRoot()); } return exportContent(context, resource.isCollection()); } /** * Checks if the given content node contains a jcr:data property * and spools its value to the output stream of the export context.
* Please note, that subclasses that define a different structure of the * content node should create their own * {@link #exportData(ExportContext, boolean, Node) exportData} method. * * @param context export context * @param isCollection true if collection * @param contentNode the content node * @throws IOException if an I/O error occurs */ protected void exportData(ExportContext context, boolean isCollection, Node contentNode) throws IOException, RepositoryException { if (contentNode.hasProperty(JcrConstants.JCR_DATA)) { Property p = contentNode.getProperty(JcrConstants.JCR_DATA); IOUtil.spool(p.getStream(), context.getOutputStream()); } // else: stream undefined -> content length was not set } } ******************************************************************************************************************* Declare the IOHandler: [...] *** * [...] ****************************************************************************************************** END ****************************************************************************************************** Just to recall it, tips about the behaviour of the garbage collector and links? (asked on previous posts). Thanks for your attention! 2012/4/6 Francisco Carriedo Scher > Hi there, > > right after posting the last question i found a helpful one: > > > http://jackrabbit.510166.n4.nabble.com/Using-nt-linkedFile-s-in-WebDav-td513737.html > > Anyway, i am pretty interested in the behaviour of the garbage collector > respecting the links (will i obtain the same behaviour than the links in > Unix?). > > Thank you very much for your attention! > > > > > > > > > > 2012/4/5 Francisco Carriedo Scher > >> Hi there, >> >> i am creating now nt:linkedfile nodes to nt:file nodes correctly but as >> i tried to access the contents through the browser i am not getting the >> content actually and getting an empty directory listing instead (the same >> of accessing an empty nt:folder node. By the way i noticed that nt:file >> nodes are exposed in the browser like this: >> >> http://localhost:8080/name/repository/default/file.jpg >> >> and linked files like this (note the ending backslash): >> >> http://localhost:8080/name/repository/default/linkedfile.jpg*/* >> >> >> The code i am using is the following and i access the repository through >> Webdav: >> >> *// Node to place the nt:linkedfile node* >> folderNode = session.getNode(directoryForLink); >> *// The nt:file node the new link will point to* >> fileToLink = session.getNode(pathToLink); >> *// Creating the link node...* >> newLink = folderNode.addNode(linkname, >> JcrConstants.NT_LINKEDFILE); >> *// Adding the content as a reference to the "real" content* >> newLink.setProperty("jcr:content", >> fileToLink.getNode("jcr:content")); >> session.save(); >> >> Is this the expected behaviour? What else should i do to get the linked >> files exposing the content through the browser as if they were files? >> >> >> Additionally, will the scenario described above (files, linked files, >> exposing everything through Webdav) work correctly with the garbage >> collection running? By working i mean than the following would go fine: >> >> 1) User A stores a photo file myPhoto.jpg >> 2) User B stores a link to myPhoto.jpg named BsphotoFile.jpg >> 3) User A decides to delete myPhoto.jpg file >> 4) Is B still able to access the BsphotoFile.jpg? >> >> I expect the garbage collection to work similar to Unix links (deleting >> link only deletes the file when it is the last link) but i prefer to >> ensure, any info about this? >> >> >> Thanks for your attention in advance! >> >> Regards. >> >> >> >> >> 2012/3/22 Francisco Carriedo Scher >> >>> Thank you very much David, i was trying to clone the procedure of >>> creating a nt:file node, setting the REFERENCE as a property worked >>> perfectly and the link is created. >>> >>> Thank you very much for your time! >>> >>> >>> 2012/3/21 David Buchmann >>> >>>> -----BEGIN PGP SIGNED MESSAGE----- >>>> Hash: SHA1 >>>> >>>> answer is inline >>>> >>>> Am 20.03.2012 23:40, schrieb Francisco Carriedo Scher: >>>> > Thanks Lukas for your quick response, anyway i'm affraid i am still >>>> missing >>>> > something... >>>> > >>>> > First i add the "mix:referenceable" not only to the nt:file node but >>>> to >>>> > it's jcr:content node too for the nt:file to be linked later: >>>> > >>>> > >>>> > Node fileNode = folderNode.addNode(file.getName(), "nt:file"); >>>> > fileNode.addMixin("mix:referenceable"); >>>> > Node resNode = fileNode.addNode("jcr:content", "nt:resource"); >>>> > resNode.addMixin("mix:referenceable"); >>>> > resNode.setProperty("jcr:mimeType", mimeType); >>>> > resNode.setProperty("jcr:encoding", encoding); >>>> > resNode.setProperty("jcr:data", binary); >>>> > session.save(); >>>> > >>>> > >>>> > and then tried this code: >>>> > >>>> > folderNode = session.getNode(directoryForLink); >>>> > fileToLink = session.getNode(pathToLink); >>>> > >>>> > for (NodeType aux : fileToLink.getMixinNodeTypes()) >>>> > System.out.println(aux.getName()); >>>> > *// PRINTS: mix:referenceable* >>>> > >>>> > resNode = fileToLink.getNode("jcr:content"); >>>> > >>>> > for (NodeType aux : resNode.getMixinNodeTypes()) >>>> > System.out.println(aux.getName()); >>>> > *// PRINTS: NOTHING* >>>> > >>>> > newLink = folderNode.addNode(linkname, >>>> > JcrConstants.NT_LINKEDFILE); >>>> > newLink.addNode(JcrConstants.JCR_CONTENT, >>>> > resNode.getIdentifier()); >>>> >>>> you try to add a node with the name that is in JCR_CONTENT and the type >>>> of the identifier. that makes no sense for jcr. the reference is a >>>> property. a child node can never be a reference. >>>> you want to do something like: >>>> newLink.setProperty("jcr:content", resNode); >>>> >>>> then you can do link.getProperty("jcr:content").getNode() to get the >>>> referenced node. >>>> >>>> > *// EXCEPTION RAISES (during the line above) * >>>> > session.save(); >>>> > >>>> > and got this exception: >>>> > >>>> > javax.jcr.nodetype.NoSuchNodeTypeException: >>>> > {}c01df2eb-7af0-49c7-a7fd-1a4fbc3b9822 >>>> > >>>> > >>>> > Any idea? Thanks for your attention! >>>> > >>>> > >>>> > >>>> > >>>> > 2012/3/20 Lukas Kahwe Smith >>>> > >>>> >> >>>> >> On Mar 20, 2012, at 17:31 , Francisco Carriedo Scher wrote: >>>> >> >>>> >>> Hello, >>>> >>> >>>> >>> i have been trying to create a nt:linkedFile node but i don't know >>>> what >>>> >> is >>>> >>> "REFERENCE" in >>>> >>> >>>> >>> [nt:linkedFile] > nt:hierarchyNode >>>> >>> primaryitem jcr:content >>>> >>> - jcr:content (REFERENCE) mandatory >>>> >>> >>>> >>> I have tried with the path of the node i want to link, a reference >>>> >> obtained >>>> >>> through JcrUtils.getReferences(nodeToLink)... But different >>>> exceptions >>>> >>> arised. >>>> >> >>>> >> >>>> >> references work on UUID's >>>> >> the target node needs to have the mixing type "mix:referenceable" >>>> which >>>> >> would give it a UUID automatically on save. >>>> >> >>>> >> regards, >>>> >> Lukas Kahwe Smith >>>> >> mls@pooteeweet.org >>>> >> >>>> >> >>>> >> >>>> >> >>>> > >>>> >>>> - -- >>>> Liip AG // Agile Web Development // T +41 26 422 25 11 >>>> CH-1700 Fribourg // PGP 0xA581808B // www.liip.ch >>>> -----BEGIN PGP SIGNATURE----- >>>> Version: GnuPG v1.4.10 (GNU/Linux) >>>> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ >>>> >>>> iEYEARECAAYFAk9pnVwACgkQqBnXnqWBgIv48ACfUIgy5KBnVkr3NK7iRB30LIiv >>>> jT4AoLNruVeXXYM1hOCuZ06Ojoy2DOYu >>>> =msAN >>>> -----END PGP SIGNATURE----- >>>> >>> >>> >> > --20cf303bfae6b82fc604bd0117f3--