blob: 2637face257bf61e95ddb5ecc67853d08c2052e3 [file] [log] [blame]
/*
* 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.myfaces.extensions.scripting.api;
import org.apache.myfaces.extensions.scripting.core.util.FileUtils;
import java.io.File;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Configuration class for our ext-scripting system.
* It keeps all internal configuration data needed
* by the various part of the system.
* <p/>
* It is pre initialized in our init stages
* and later accessed only readonly.
*/
public class Configuration {
/**
* the source dirs per scripting engine
*/
volatile Map<Integer, CopyOnWriteArrayList<String>> _sourceDirs = new ConcurrentHashMap<Integer, CopyOnWriteArrayList<String>>();
/**
* the target compile path
*/
volatile File _compileTarget = FileUtils.getTempDir();
/**
* if set to true we do an initial compile step upon loading
*/
boolean _initialCompile = true;
/**
* the package whitelist used by our system
* to determine which packages are under control.
* <p/>
* Note an empty whitelist means, all packages with sourcedirs attached to.
*/
Set<String> _packageWhiteList = new HashSet<String>();
/**
* Optional additional classpath for the compilers
* to be able to pick up additional compile jars
*/
List<String> _additionalClassPath = new LinkedList<String>();
/**
* we keep track of separate resource dirs
* for systems which can use resource loaders
* <p/>
* so that we can load various resources as well
* from separate source directories instead
*/
volatile List<String> _resourceDirs = new CopyOnWriteArrayList<String>();
@SuppressWarnings("unchecked")
public Collection<String> getSourceDirs(int scriptingEngine) {
Collection<String> retVal = _sourceDirs.get(scriptingEngine);
if (retVal == null) return Collections.EMPTY_SET;
return retVal;
}
public Collection<String> getAllSourceDirs() {
Set<String> retVal = new HashSet(10);
for (Map.Entry<Integer, CopyOnWriteArrayList<String>> entry : _sourceDirs.entrySet()) {
for (String dir : entry.getValue()) {
retVal.add(dir);
}
}
return retVal;
}
/**
* returns a set of whitelisted subdirs hosting the source
*
* @param scriptingEngine the scripting engine for which the dirs have to be determined
* (note every scripting engine has a unique integer value)
* @return the current whitelisted dirs hosting the sources
*/
public Collection<String> getWhitelistedSourceDirs(int scriptingEngine) {
List<String> origSourceDirs = _sourceDirs.get(scriptingEngine);
if (_packageWhiteList.isEmpty()) {
return origSourceDirs;
}
return mergeWhitelisted(origSourceDirs);
}
/**
* merges the whitelisted packages with the sourcedirs and generates a final list
* which left join of both sets - the ones which do not exist in reality
*
* @param origSourceDirs the original source dirs
* @return the joined existing subset of all directories which exist
*/
private Collection<String> mergeWhitelisted(List<String> origSourceDirs) {
List<String> retVal = new ArrayList<String>(_packageWhiteList.size() * origSourceDirs.size() + origSourceDirs.size());
for (String whitelisted : _packageWhiteList) {
whitelisted = whitelisted.replaceAll("\\.", FileUtils.getFileSeparatorForRegex());
for (String sourceDir : origSourceDirs) {
String newSourceDir = sourceDir + File.separator + whitelisted;
if ((new File(newSourceDir)).exists()) {
retVal.add(newSourceDir);
}
}
}
return retVal;
}
/**
* Add a new source dir for the corresponding scripting engine
*
* @param scriptingEngine integer value marking the corresponding engine
* @param sourceDir the source directory added to the existing source dir list
*/
public void addSourceDir(int scriptingEngine, String sourceDir) {
CopyOnWriteArrayList<String> dirs = _sourceDirs.get(scriptingEngine);
if (dirs == null) {
dirs = new CopyOnWriteArrayList<String>();
_sourceDirs.put(scriptingEngine, dirs);
}
dirs.add(sourceDir);
}
/**
* <p>Resolves and returns a File handle that represents the class file of
* the given class on the file system. However, note that this method only
* returns <code>null</code> if an error occured while resolving the class
* file. A non-null valuee doesn't necessarily mean that the class file
* actually exists. In oder to check the existence call the according
* method on the returned object.</p>
*
* @param className the name of the class that you want to resolve
* @return a File handle that represents the class file of the given class
* on the file system
* @see java.io.File#exists()
*/
public File resolveClassFile(String className) {
//if(className.contains("rg/apache/myfaces/javaloader/componentTest/JavaTestComponent$PropertyKeys")) {
// System.out.println("Debuginfo found");
//}
//int subClassPos = className.indexOf("$");
//className = (subClassPos != -1)? className.substring(0, subClassPos) :className;
return new File(getCompileTarget(),
className.replaceAll("\\.", "/").concat(".class"));
}
public File getCompileTarget() {
return _compileTarget;
}
public void addResourceDir(String dir) {
_resourceDirs.add(dir);
}
public List<String> getResourceDirs() {
return _resourceDirs;
}
public boolean isInitialCompile() {
return _initialCompile;
}
public void setInitialCompile(boolean initialCompile) {
this._initialCompile = initialCompile;
}
public void addWhitelistPackage(String pkg) {
_packageWhiteList.add(pkg);
}
public Set<String> getPackageWhiteList() {
return _packageWhiteList;
}
public void setPackageWhiteList(Set<String> packageWhiteList) {
this._packageWhiteList = packageWhiteList;
}
public void addAdditionalClassPath(String path) {
_additionalClassPath.add(path);
}
public List<String> getAdditionalClassPath() {
return _additionalClassPath;
}
public void setAdditionalClassPath(List<String> additionalClassPath) {
this._additionalClassPath = additionalClassPath;
}
}