All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.naming.resources.VirtualDirContext Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.naming.resources;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import javax.naming.NamingException;
import javax.naming.directory.Attributes;

import org.apache.naming.NamingEntry;

/**
 * Extended FileDirContext implementation that allows to expose multiple
 * directories of the filesystem under a single webapp, a feature mainly used
 * for development with IDEs.
 * This should be used in conjunction with
 * {@link org.apache.catalina.loader.VirtualWebappLoader}.
 *
 * Sample context xml configuration:
 *
 * 
 * <Context path="/mywebapp" docBase="/Users/theuser/mywebapp/src/main/webapp" >
 *   <Resources className="org.apache.naming.resources.VirtualDirContext"
 *              extraResourcePaths="/pictures=/Users/theuser/mypictures,/movies=/Users/theuser/mymovies" />
 *   <Loader className="org.apache.catalina.loader.VirtualWebappLoader"
 *              virtualClasspath="/Users/theuser/mywebapp/target/classes" />
 *   <JarScanner scanAllDirectories="true" />
 * </Context>
 * 
 *
 *
 * This is not meant to be used for production.
 * Its meant to ease development with IDE's without the
 * need for fully republishing jars in WEB-INF/lib
 *
 *
 * @author Fabrizio Giustina
 * @version $Id: VirtualDirContext.java 1307600 2012-03-30 20:33:27Z kkolinko $
 */
public class VirtualDirContext extends FileDirContext {
    private String extraResourcePaths = "";
    private Map> mappedResourcePaths;

    /**
     * 

* Allows to map a path of the filesystem to a path in the webapp. Multiple * filesystem paths can be mapped to the same path in the webapp. Filesystem * path and virtual path must be separated by an equal sign. Pairs of paths * must be separated by a comma. *

* Example: * /=/Users/slaurent/mywebapp/src/main/webapp;/pictures=/Users/slaurent/sharedpictures * *

* The path to the docBase must not be added here, otherwise resources would * be listed twice. *

* * @param path */ public void setExtraResourcePaths(String path) { extraResourcePaths = path; } /** * {@inheritDoc} */ @Override public void allocate() { super.allocate(); mappedResourcePaths = new HashMap>(); StringTokenizer tkn = new StringTokenizer(extraResourcePaths, ","); while (tkn.hasMoreTokens()) { String resSpec = tkn.nextToken(); if (resSpec.length() > 0) { int idx = resSpec.indexOf('='); String path; if (idx <= 0) { path = ""; } else { if (resSpec.startsWith("/=")) { resSpec = resSpec.substring(1); idx--; } path = resSpec.substring(0, idx); } String dir = resSpec.substring(idx + 1); List resourcePaths = mappedResourcePaths.get(path); if (resourcePaths == null) { resourcePaths = new ArrayList(); mappedResourcePaths.put(path, resourcePaths); } resourcePaths.add(dir); } } if (mappedResourcePaths.isEmpty()) { mappedResourcePaths = null; } } /** * {@inheritDoc} */ @Override public void release() { mappedResourcePaths = null; super.release(); } @Override public Attributes getAttributes(String name) throws NamingException { NamingException initialException; try { // first try the normal processing, if it fails try with extra // resources Attributes attributes = super.getAttributes(name); return attributes; } catch (NamingException exc) { initialException = exc; } if (mappedResourcePaths != null) { for (Map.Entry> mapping : mappedResourcePaths.entrySet()) { String path = mapping.getKey(); List dirList = mapping.getValue(); String resourcesDir = dirList.get(0); if (name.equals(path)) { File f = new File(resourcesDir); if (f.exists() && f.canRead()) { return new FileResourceAttributes(f); } } path += "/"; if (name.startsWith(path)) { String res = name.substring(path.length()); File f = new File(resourcesDir + "/" + res); if (f.exists() && f.canRead()) { return new FileResourceAttributes(f); } } } } throw initialException; } @Override protected File file(String name) { File file = super.file(name); if (file != null || mappedResourcePaths == null) { return file; } // If not found under docBase, try our other resources // Ensure name string begins with a slash if (name.length() > 0 && name.charAt(0) != '/') { name = "/" + name; } for (Map.Entry> mapping : mappedResourcePaths.entrySet()) { String path = mapping.getKey(); List dirList = mapping.getValue(); if (name.equals(path)) { for (String resourcesDir : dirList) { file = new File(resourcesDir); if (file.exists() && file.canRead()) { return file; } } } if (name.startsWith(path + "/")) { String res = name.substring(path.length()); for (String resourcesDir : dirList) { file = new File(resourcesDir, res); if (file.exists() && file.canRead()) { return file; } } } } return null; } @Override protected List list(File file) { List entries = super.list(file); if (mappedResourcePaths != null && !mappedResourcePaths.isEmpty()) { Set entryNames = new HashSet(entries.size()); for (NamingEntry entry : entries) { entryNames.add(entry.name); } // Add appropriate entries from the extra resource paths String absPath = file.getAbsolutePath(); if (absPath.startsWith(getDocBase() + File.separator)) { String relPath = absPath.substring(getDocBase().length()); String fsRelPath = relPath.replace(File.separatorChar, '/'); for (Map.Entry> mapping : mappedResourcePaths.entrySet()) { String path = mapping.getKey(); List dirList = mapping.getValue(); String res = null; if (fsRelPath.equals(path)) { res = ""; } else if (fsRelPath.startsWith(path + "/")) { res = relPath.substring(path.length()); } if (res != null) { for (String resourcesDir : dirList) { File f = new File(resourcesDir, res); if (f.exists() && f.canRead() && f.isDirectory()) { List virtEntries = super.list(f); for (NamingEntry entry : virtEntries) { // filter duplicate if (!entryNames.contains(entry.name)) { entryNames.add(entry.name); entries.add(entry); } } } } } } } } return entries; } @Override protected Object doLookup(String name) { Object retSuper = super.doLookup(name); if (retSuper != null || mappedResourcePaths == null) { return retSuper; } // Perform lookup using the extra resource paths for (Map.Entry> mapping : mappedResourcePaths.entrySet()) { String path = mapping.getKey(); List dirList = mapping.getValue(); if (name.equals(path)) { for (String resourcesDir : dirList) { File f = new File(resourcesDir); if (f.exists() && f.canRead()) { if (f.isFile()) { return new FileResource(f); } else { // never goes here, if f is a directory the super // implementation already returned a value } } } } path += "/"; if (name.startsWith(path)) { String res = name.substring(path.length()); for (String resourcesDir : dirList) { File f = new File(resourcesDir + "/" + res); if (f.exists() && f.canRead()) { if (f.isFile()) { return new FileResource(f); } else { // never goes here, if f is a directory the super // implementation already returned a value } } } } } return retSuper; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy