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.xml.sax.SAXException; 038 039import org.ametys.plugins.repositoryapp.RepositoryProvider; 040 041/** 042 * {@link Reader} for exposing a binary property from a JCR repository.<br> 043 * Mime type can be forced by using parameter <code>mime-type</code>. 044 */ 045public class BinaryPropertyReader extends ServiceableReader 046{ 047 048 /** The repository provider. */ 049 protected RepositoryProvider _repositoryProvider; 050 051 private Node _node; 052 private Property _property; 053 054 @Override 055 public void service(ServiceManager serviceManager) throws ServiceException 056 { 057 super.service(serviceManager); 058 _repositoryProvider = (RepositoryProvider) serviceManager.lookup(RepositoryProvider.ROLE); 059 } 060 061 @Override 062 public void setup(SourceResolver res, Map objModel, String src, Parameters par) throws ProcessingException, SAXException, IOException 063 { 064 super.setup(res, objModel, src, par); 065 066 Session session = null; 067 String workspaceName = null; 068 069 try 070 { 071 workspaceName = parameters.getParameter("workspace"); 072 073 session = _repositoryProvider.getSession(workspaceName); 074 } 075 catch (Exception e) 076 { 077 throw new ProcessingException("Unable to retrieve repository", e); 078 } 079 080 try 081 { 082 String path = par.getParameter("path", ""); 083 String relPath = RepositoryDao.removeLeadingSlash(path); 084 085 _node = session.getRootNode().getNode(relPath); 086 087 String name = par.getParameter("property", null); 088 _property = _node.getProperty(name); 089 } 090 catch (RepositoryException e) 091 { 092 throw new ProcessingException(e); 093 } 094 } 095 096 @Override 097 public String getMimeType() 098 { 099 try 100 { 101 if (_node.hasProperty("jcr:mimeType")) 102 { 103 return _node.getProperty("jcr:mimeType").getString(); 104 } 105 } 106 catch (RepositoryException e) 107 { 108 // Nothing 109 } 110 111 return "application/unknown"; 112 } 113 114 private String _getName () throws RepositoryException 115 { 116 if ("nt:resource".equals(_node.getPrimaryNodeType().getName())) 117 { 118 return _node.getParent().getName(); 119 } 120 121 return _property.getName(); 122 } 123 124 @SuppressWarnings("deprecation") 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}