001/* 002 * Copyright 2010 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.workspaces.repository.jcr; 017 018import java.io.IOException; 019import java.io.InputStream; 020import java.util.Map; 021 022import javax.jcr.Node; 023import javax.jcr.Property; 024import javax.jcr.RepositoryException; 025import javax.jcr.Session; 026 027import org.apache.avalon.framework.parameters.Parameters; 028import org.apache.avalon.framework.service.ServiceException; 029import org.apache.avalon.framework.service.ServiceManager; 030import org.apache.cocoon.ProcessingException; 031import org.apache.cocoon.environment.ObjectModelHelper; 032import org.apache.cocoon.environment.Response; 033import org.apache.cocoon.environment.SourceResolver; 034import org.apache.cocoon.reading.Reader; 035import org.apache.cocoon.reading.ServiceableReader; 036import org.apache.commons.io.IOUtils; 037import org.apache.jackrabbit.JcrConstants; 038import org.xml.sax.SAXException; 039 040import org.ametys.plugins.repositoryapp.RepositoryProvider; 041 042/** 043 * {@link Reader} for exposing a binary property from a JCR repository.<br> 044 * Mime type can be forced by using parameter <code>mime-type</code>. 045 */ 046public class BinaryPropertyReader extends ServiceableReader 047{ 048 049 /** The repository provider. */ 050 protected RepositoryProvider _repositoryProvider; 051 052 private Node _node; 053 private Property _property; 054 055 @Override 056 public void service(ServiceManager serviceManager) throws ServiceException 057 { 058 super.service(serviceManager); 059 _repositoryProvider = (RepositoryProvider) serviceManager.lookup(RepositoryProvider.ROLE); 060 } 061 062 @Override 063 public void setup(SourceResolver res, Map objModel, String src, Parameters par) throws ProcessingException, SAXException, IOException 064 { 065 super.setup(res, objModel, src, par); 066 067 Session session = null; 068 String workspaceName = null; 069 070 try 071 { 072 workspaceName = parameters.getParameter("workspace"); 073 074 session = _repositoryProvider.getSession(workspaceName); 075 } 076 catch (Exception e) 077 { 078 throw new ProcessingException("Unable to retrieve repository", e); 079 } 080 081 try 082 { 083 String path = par.getParameter("path", ""); 084 String relPath = RepositoryDao.removeLeadingSlash(path); 085 086 _node = session.getRootNode().getNode(relPath); 087 088 String name = par.getParameter("property", null); 089 _property = _node.getProperty(name); 090 } 091 catch (RepositoryException e) 092 { 093 throw new ProcessingException(e); 094 } 095 } 096 097 @Override 098 public String getMimeType() 099 { 100 try 101 { 102 if (_node.hasProperty(JcrConstants.JCR_MIMETYPE)) 103 { 104 return _node.getProperty(JcrConstants.JCR_MIMETYPE).getString(); 105 } 106 } 107 catch (RepositoryException e) 108 { 109 // Nothing 110 } 111 112 return "application/unknown"; 113 } 114 115 private String _getName () throws RepositoryException 116 { 117 if (JcrConstants.NT_RESOURCE.equals(_node.getPrimaryNodeType().getName())) 118 { 119 return _node.getParent().getName(); 120 } 121 122 return _property.getName(); 123 } 124 125 public void generate() throws IOException, SAXException, ProcessingException 126 { 127 String path = null; 128 try 129 { 130 String name = _getName (); 131 name = name.replaceAll("\\\\", "\\\\\\\\"); 132 name = name.replaceAll("\\\"", "\\\\\\\""); 133 134 path = _property.getPath(); 135 136 Response response = ObjectModelHelper.getResponse(objectModel); 137 138 response.setHeader("Content-Length", Long.toString(_property.getLength())); 139 response.setHeader("Content-Disposition", "attachment; filename=\"" + name + "\""); 140 141 try (InputStream is = _property.getBinary().getStream()) 142 { 143 IOUtils.copy(is, out); 144 } 145 } 146 catch (Exception e) 147 { 148 throw new ProcessingException("Unable to download binary property of path " + path, e); 149 } 150 finally 151 { 152 IOUtils.closeQuietly(out); 153 } 154 } 155}