001/* 002 * Copyright 2002-2013 the original author or authors. 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 * https://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 */ 016 017package org.springframework.mock.web.portlet; 018 019import java.io.File; 020import java.io.IOException; 021import java.io.InputStream; 022import java.net.MalformedURLException; 023import java.net.URL; 024import java.util.Collections; 025import java.util.Enumeration; 026import java.util.HashSet; 027import java.util.LinkedHashMap; 028import java.util.LinkedHashSet; 029import java.util.Map; 030import java.util.Set; 031import javax.activation.FileTypeMap; 032import javax.portlet.PortletContext; 033import javax.portlet.PortletRequestDispatcher; 034 035import org.apache.commons.logging.Log; 036import org.apache.commons.logging.LogFactory; 037 038import org.springframework.core.io.DefaultResourceLoader; 039import org.springframework.core.io.Resource; 040import org.springframework.core.io.ResourceLoader; 041import org.springframework.util.Assert; 042import org.springframework.web.util.WebUtils; 043 044/** 045 * Mock implementation of the {@link javax.portlet.PortletContext} interface. 046 * 047 * @author John A. Lewis 048 * @author Juergen Hoeller 049 * @since 2.0 050 */ 051public class MockPortletContext implements PortletContext { 052 053 private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir"; 054 055 056 private final Log logger = LogFactory.getLog(getClass()); 057 058 private final String resourceBasePath; 059 060 private final ResourceLoader resourceLoader; 061 062 private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); 063 064 private final Map<String, String> initParameters = new LinkedHashMap<String, String>(); 065 066 private String portletContextName = "MockPortletContext"; 067 068 private Set<String> containerRuntimeOptions = new LinkedHashSet<String>(); 069 070 071 /** 072 * Create a new MockPortletContext with no base path and a 073 * DefaultResourceLoader (i.e. the classpath root as WAR root). 074 * @see org.springframework.core.io.DefaultResourceLoader 075 */ 076 public MockPortletContext() { 077 this("", null); 078 } 079 080 /** 081 * Create a new MockPortletContext using a DefaultResourceLoader. 082 * @param resourceBasePath the WAR root directory (should not end with a slash) 083 * @see org.springframework.core.io.DefaultResourceLoader 084 */ 085 public MockPortletContext(String resourceBasePath) { 086 this(resourceBasePath, null); 087 } 088 089 /** 090 * Create a new MockPortletContext, using the specified ResourceLoader 091 * and no base path. 092 * @param resourceLoader the ResourceLoader to use (or null for the default) 093 */ 094 public MockPortletContext(ResourceLoader resourceLoader) { 095 this("", resourceLoader); 096 } 097 098 /** 099 * Create a new MockPortletContext. 100 * @param resourceBasePath the WAR root directory (should not end with a slash) 101 * @param resourceLoader the ResourceLoader to use (or null for the default) 102 */ 103 public MockPortletContext(String resourceBasePath, ResourceLoader resourceLoader) { 104 this.resourceBasePath = (resourceBasePath != null ? resourceBasePath : ""); 105 this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader()); 106 107 // Use JVM temp dir as PortletContext temp dir. 108 String tempDir = System.getProperty(TEMP_DIR_SYSTEM_PROPERTY); 109 if (tempDir != null) { 110 this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir)); 111 } 112 } 113 114 /** 115 * Build a full resource location for the given path, 116 * prepending the resource base path of this MockPortletContext. 117 * @param path the path as specified 118 * @return the full resource path 119 */ 120 protected String getResourceLocation(String path) { 121 if (!path.startsWith("/")) { 122 path = "/" + path; 123 } 124 return this.resourceBasePath + path; 125 } 126 127 128 @Override 129 public String getServerInfo() { 130 return "MockPortal/1.0"; 131 } 132 133 @Override 134 public PortletRequestDispatcher getRequestDispatcher(String path) { 135 if (!path.startsWith("/")) { 136 throw new IllegalArgumentException( 137 "PortletRequestDispatcher path at PortletContext level must start with '/'"); 138 } 139 return new MockPortletRequestDispatcher(path); 140 } 141 142 @Override 143 public PortletRequestDispatcher getNamedDispatcher(String path) { 144 return null; 145 } 146 147 @Override 148 public InputStream getResourceAsStream(String path) { 149 Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); 150 try { 151 return resource.getInputStream(); 152 } 153 catch (IOException ex) { 154 logger.info("Couldn't open InputStream for " + resource, ex); 155 return null; 156 } 157 } 158 159 @Override 160 public int getMajorVersion() { 161 return 2; 162 } 163 164 @Override 165 public int getMinorVersion() { 166 return 0; 167 } 168 169 @Override 170 public String getMimeType(String filePath) { 171 return MimeTypeResolver.getMimeType(filePath); 172 } 173 174 @Override 175 public String getRealPath(String path) { 176 Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); 177 try { 178 return resource.getFile().getAbsolutePath(); 179 } 180 catch (IOException ex) { 181 logger.info("Couldn't determine real path of resource " + resource, ex); 182 return null; 183 } 184 } 185 186 @Override 187 public Set<String> getResourcePaths(String path) { 188 Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); 189 try { 190 File file = resource.getFile(); 191 String[] fileList = file.list(); 192 String prefix = (path.endsWith("/") ? path : path + "/"); 193 Set<String> resourcePaths = new HashSet<String>(fileList.length); 194 for (String fileEntry : fileList) { 195 resourcePaths.add(prefix + fileEntry); 196 } 197 return resourcePaths; 198 } 199 catch (IOException ex) { 200 logger.info("Couldn't get resource paths for " + resource, ex); 201 return null; 202 } 203 } 204 205 @Override 206 public URL getResource(String path) throws MalformedURLException { 207 Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); 208 try { 209 return resource.getURL(); 210 } 211 catch (IOException ex) { 212 logger.info("Couldn't get URL for " + resource, ex); 213 return null; 214 } 215 } 216 217 @Override 218 public Object getAttribute(String name) { 219 return this.attributes.get(name); 220 } 221 222 @Override 223 public Enumeration<String> getAttributeNames() { 224 return Collections.enumeration(new LinkedHashSet<String>(this.attributes.keySet())); 225 } 226 227 @Override 228 public void setAttribute(String name, Object value) { 229 if (value != null) { 230 this.attributes.put(name, value); 231 } 232 else { 233 this.attributes.remove(name); 234 } 235 } 236 237 @Override 238 public void removeAttribute(String name) { 239 this.attributes.remove(name); 240 } 241 242 public void addInitParameter(String name, String value) { 243 Assert.notNull(name, "Parameter name must not be null"); 244 this.initParameters.put(name, value); 245 } 246 247 @Override 248 public String getInitParameter(String name) { 249 Assert.notNull(name, "Parameter name must not be null"); 250 return this.initParameters.get(name); 251 } 252 253 @Override 254 public Enumeration<String> getInitParameterNames() { 255 return Collections.enumeration(this.initParameters.keySet()); 256 } 257 258 @Override 259 public void log(String message) { 260 logger.info(message); 261 } 262 263 @Override 264 public void log(String message, Throwable t) { 265 logger.info(message, t); 266 } 267 268 public void setPortletContextName(String portletContextName) { 269 this.portletContextName = portletContextName; 270 } 271 272 @Override 273 public String getPortletContextName() { 274 return this.portletContextName; 275 } 276 277 public void addContainerRuntimeOption(String key) { 278 this.containerRuntimeOptions.add(key); 279 } 280 281 @Override 282 public Enumeration<String> getContainerRuntimeOptions() { 283 return Collections.enumeration(this.containerRuntimeOptions); 284 } 285 286 287 /** 288 * Inner factory class used to just introduce a Java Activation Framework 289 * dependency when actually asked to resolve a MIME type. 290 */ 291 private static class MimeTypeResolver { 292 293 public static String getMimeType(String filePath) { 294 return FileTypeMap.getDefaultFileTypeMap().getContentType(filePath); 295 } 296 } 297 298}