001/* 002 * Copyright 2019 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.plugins.core.ui.parameter.files; 017 018import java.util.ArrayList; 019import java.util.Collection; 020import java.util.Date; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024 025import org.apache.avalon.framework.context.Context; 026import org.apache.avalon.framework.context.ContextException; 027import org.apache.avalon.framework.context.Contextualizable; 028import org.apache.avalon.framework.parameters.Parameters; 029import org.apache.avalon.framework.service.ServiceException; 030import org.apache.avalon.framework.service.ServiceManager; 031import org.apache.cocoon.acting.ServiceableAction; 032import org.apache.cocoon.environment.ObjectModelHelper; 033import org.apache.cocoon.environment.Redirector; 034import org.apache.cocoon.environment.Request; 035import org.apache.cocoon.environment.SourceResolver; 036import org.apache.commons.lang3.StringUtils; 037import org.apache.excalibur.source.TraversableSource; 038 039import org.ametys.core.cocoon.JSonReader; 040import org.ametys.core.util.DateUtils; 041 042/** 043 * Abstract action for getting child files/folders of a local application folder 044 */ 045public abstract class AbstractGetFilesAction extends ServiceableAction implements Contextualizable 046{ 047 /** The cocoon context */ 048 protected org.apache.cocoon.environment.Context _cocoonContext; 049 /** The source resolver */ 050 protected org.apache.excalibur.source.SourceResolver _srcResolver; 051 052 @Override 053 public void service(ServiceManager smanager) throws ServiceException 054 { 055 _srcResolver = (org.apache.excalibur.source.SourceResolver) smanager.lookup(org.apache.excalibur.source.SourceResolver.ROLE); 056 } 057 058 @Override 059 public void contextualize(Context context) throws ContextException 060 { 061 _cocoonContext = (org.apache.cocoon.environment.Context) context.get(org.apache.cocoon.Constants.CONTEXT_ENVIRONMENT_CONTEXT); 062 } 063 064 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 065 { 066 Request request = ObjectModelHelper.getRequest(objectModel); 067 068 String path = StringUtils.defaultString(request.getParameter("path"), ""); 069 070 String rootURI = getRootURI(request); 071 TraversableSource rootDir = (TraversableSource) _srcResolver.resolveURI(rootURI); 072 TraversableSource currentDir = (TraversableSource) _srcResolver.resolveURI(rootURI + (path.length() > 0 ? "/" + path : "")); 073 074 List<Map<String, Object>> nodes = new ArrayList<>(); 075 076 if (currentDir.exists()) 077 { 078 for (TraversableSource child : (Collection<TraversableSource>) currentDir.getChildren()) 079 { 080 if (!isIgnoredSource(child)) 081 { 082 if (child.isCollection()) 083 { 084 nodes.add(_collection2JsonObject(child, rootDir)); 085 } 086 else 087 { 088 nodes.add(_resource2JsonObject(child, rootDir)); 089 } 090 } 091 } 092 } 093 094 Map<String, Object> result = new HashMap<>(); 095 result.put("nodes", nodes); 096 097 request.setAttribute(JSonReader.OBJECT_TO_READ, result); 098 return EMPTY_MAP; 099 } 100 101 /** 102 * Get the URI of root directory such as 'context://WEB-INF/param' 103 * @param request the request 104 * @return The root URI 105 */ 106 protected abstract String getRootURI (Request request); 107 108 /** 109 * Test if the source has to be ignored 110 * @param source The source 111 * @return true if the source has to be ignored 112 */ 113 protected boolean isIgnoredSource (TraversableSource source) 114 { 115 return false; 116 } 117 118 /** 119 * Convert collection to JSON object 120 * @param folder the folder 121 * @param root the root directory 122 * @return JSON object 123 */ 124 protected Map<String, Object> _collection2JsonObject (TraversableSource folder, TraversableSource root) 125 { 126 Map<String, Object> jsonObject = new HashMap<>(); 127 jsonObject.put("type", "collection"); 128 jsonObject.put("name", folder.getName()); 129 jsonObject.put("path", _getRelativePath(root, folder)); 130 return jsonObject; 131 } 132 133 /** 134 * Convert file to JSON object 135 * @param file the file 136 * @param root the root directory 137 * @return JSON object 138 */ 139 protected Map<String, Object> _resource2JsonObject (TraversableSource file, TraversableSource root) 140 { 141 Map<String, Object> jsonObject = new HashMap<>(); 142 143 jsonObject.put("type", "resource"); 144 jsonObject.put("name", file.getName()); 145 jsonObject.put("path", _getRelativePath(root, file)); 146 147 jsonObject.put("size", file.getContentLength()); 148 jsonObject.put("lastModified", DateUtils.dateToString(new Date(file.getLastModified()))); 149 150 String mimeType = _cocoonContext.getMimeType(file.getName().toLowerCase()); 151 jsonObject.put("mimetype", mimeType != null ? mimeType : "application/unknown"); 152 153 return jsonObject; 154 } 155 156 /** 157 * Get the relative path from root directory 158 * @param root The root directory 159 * @param file The file 160 * @return The relative path 161 */ 162 protected String _getRelativePath (TraversableSource root, TraversableSource file) 163 { 164 String relPath = file.getURI().substring(root.getURI().length()); 165 166 if (relPath.endsWith("/")) 167 { 168 relPath = relPath.substring(0, relPath.length() - 1); 169 } 170 171 return relPath; 172 } 173 174}