Removing the compiling classloader

WW-1446


git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@443203 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Donald J. Brown
2006-09-14 02:58:59 +00:00
parent d5b0a680d2
commit bf19765045
27 changed files with 1 additions and 2107 deletions
@@ -30,8 +30,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.struts2.util.classloader.CompilingClassLoader;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
@@ -139,13 +137,7 @@ public class QuickStart {
Thread.currentThread().getContextClassLoader());
if (c.getSources() != null) {
for (Iterator iterator = c.getSources().iterator(); iterator.hasNext();) {
String source = (String) iterator.next();
File file = new File(source);
CompilingClassLoader ccl = new CompilingClassLoader(parent, file);
ccl.start();
parent = ccl;
}
System.out.print("Automatic compiling of classes no longer supported.");
}
URLClassLoader url = new MyURLClassLoader(parent);
Thread.currentThread().setContextClassLoader(url);
@@ -1,89 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader;
import java.io.File;
import org.apache.struts2.util.classloader.compilers.JavaCompiler;
import org.apache.struts2.util.classloader.compilers.eclipse.EclipseJavaCompiler;
import org.apache.struts2.util.classloader.listeners.CompilingListener;
import org.apache.struts2.util.classloader.monitor.FilesystemAlterationMonitor;
import org.apache.struts2.util.classloader.stores.MemoryResourceStore;
import org.apache.struts2.util.classloader.stores.TransactionalResourceStore;
import com.uwyn.rife.continuations.ClassByteAware;
/**
*/
public class CompilingClassLoader extends ReloadingClassLoader implements ClassByteAware {
private final TransactionalResourceStore transactionalStore;
private final JavaCompiler compiler;
public CompilingClassLoader(final ClassLoader pParent, final File pRepository) {
this(pParent, pRepository, new TransactionalResourceStore(
new MemoryResourceStore()) {
public void onStart() {
}
;
public void onStop() {
}
;
}
);
}
public CompilingClassLoader(final ClassLoader pParent, final File pRepository, final TransactionalResourceStore pStore) {
this(pParent, pRepository, pStore, new EclipseJavaCompiler());
}
public CompilingClassLoader(final ClassLoader pParent, final File pRepository,
final TransactionalResourceStore pStore, final JavaCompiler pCompiler) {
super(pParent, pRepository, pStore);
transactionalStore = pStore;
compiler = pCompiler;
}
public byte[] getClassBytes(String classname) throws ClassNotFoundException {
return transactionalStore.read(classname);
}
public void start() {
fam = new FilesystemAlterationMonitor();
// FIXME keep reference for accessing errors/warnings
listener = new CompilingListener(
reader,
compiler,
transactionalStore
) {
public void reload() {
super.reload();
CompilingClassLoader.this.reload();
}
};
fam.addListener(listener, repository);
thread = new Thread(fam);
fam.doRun();
thread.start();
}
}
@@ -1,164 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.util.classloader.listeners.CompilingListener;
import org.apache.struts2.util.classloader.listeners.ReloadingListener;
import org.apache.struts2.util.classloader.monitor.FilesystemAlterationMonitor;
import org.apache.struts2.util.classloader.readers.FileResourceReader;
import org.apache.struts2.util.classloader.readers.ResourceReader;
import org.apache.struts2.util.classloader.stores.MemoryResourceStore;
import org.apache.struts2.util.classloader.stores.ResourceStore;
import org.apache.struts2.util.classloader.stores.ResourceStoreClassLoader;
/**
*/
public class ReloadingClassLoader extends ClassLoader {
private final static Log log = LogFactory.getLog(ReloadingClassLoader.class);
private final ClassLoader parent;
private final ResourceStore store;
private final Collection reloadingListeners = new HashSet();
protected CompilingListener listener;
private ResourceStoreClassLoader delegate;
protected final ResourceReader reader;
protected final File repository;
protected FilesystemAlterationMonitor fam;
protected Thread thread;
public ReloadingClassLoader(final ClassLoader pParent, final File pRepository) {
this(pParent, pRepository, new MemoryResourceStore());
}
public ReloadingClassLoader(final ClassLoader pParent, final File pRepository, final ResourceStore pStore) {
super(pParent);
parent = pParent;
repository = pRepository;
reader = new FileResourceReader(repository);
store = pStore;
delegate = new ResourceStoreClassLoader(parent, store);
}
public void start() {
fam = new FilesystemAlterationMonitor();
fam.addListener(new ReloadingListener(store) {
protected void notifyOfCheck(boolean pReload) {
super.notifyOfCheck(pReload);
if (pReload) {
ReloadingClassLoader.this.reload();
} else {
ReloadingClassLoader.this.notifyReloadingListeners(false);
}
}
}, repository);
thread = new Thread(fam);
thread.start();
}
public void stop() {
fam.stop();
try {
thread.join();
} catch (final InterruptedException e) {
;
}
}
public void addListener(final ReloadingClassLoaderListener pListener) {
synchronized (reloadingListeners) {
reloadingListeners.add(pListener);
}
}
public boolean removeListener(final ReloadingClassLoaderListener pListener) {
synchronized (reloadingListeners) {
return reloadingListeners.remove(pListener);
}
}
protected void reload() {
log.debug("reloading");
delegate = new ResourceStoreClassLoader(parent, store);
notifyReloadingListeners(true);
}
private void notifyReloadingListeners(final boolean pReload) {
synchronized (reloadingListeners) {
for (final Iterator it = reloadingListeners.iterator(); it.hasNext();) {
final ReloadingClassLoaderListener listener = (ReloadingClassLoaderListener) it.next();
listener.hasReloaded(pReload);
}
}
}
public static String clazzName(final File base, final File file) {
final int rootLength = base.getAbsolutePath().length();
final String absFileName = file.getAbsolutePath();
final int p = absFileName.lastIndexOf('.');
final String relFileName = absFileName.substring(rootLength + 1, p);
final String clazzName = relFileName.replace(File.separatorChar, '.');
return clazzName;
}
public void clearAssertionStatus() {
delegate.clearAssertionStatus();
}
public URL getResource(String name) {
return delegate.getResource(name);
}
public InputStream getResourceAsStream(String name) {
return delegate.getResourceAsStream(name);
}
public Class loadClass(String name) throws ClassNotFoundException {
return delegate.loadClass(name);
}
public void setClassAssertionStatus(String className, boolean enabled) {
delegate.setClassAssertionStatus(className, enabled);
}
public void setDefaultAssertionStatus(boolean enabled) {
delegate.setDefaultAssertionStatus(enabled);
}
public void setPackageAssertionStatus(String packageName, boolean enabled) {
delegate.setPackageAssertionStatus(packageName, enabled);
}
}
@@ -1,25 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader;
/**
*/
public interface ReloadingClassLoaderListener {
void hasReloaded(final boolean pReload);
}
@@ -1,34 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.compilers;
import org.apache.struts2.util.classloader.problems.CompilationProblemHandler;
import org.apache.struts2.util.classloader.readers.ResourceReader;
import org.apache.struts2.util.classloader.stores.ResourceStore;
/**
*/
public interface JavaCompiler {
void compile(
final String[] pClazzNames,
final ResourceReader pReader,
final ResourceStore pStore,
final CompilationProblemHandler pProblemHandler
);
}
@@ -1,24 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.compilers;
public interface JavaCompilerFactory {
JavaCompiler createCompiler(final Object pHint);
}
@@ -1,22 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.compilers;
public interface JavaCompilerSettings {
}
@@ -1,74 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.compilers.eclipse;
import org.apache.struts2.util.classloader.problems.CompilationProblem;
import org.eclipse.jdt.core.compiler.IProblem;
public class EclipseCompilationProblem implements CompilationProblem {
private final IProblem problem;
public EclipseCompilationProblem(final IProblem pProblem) {
problem = pProblem;
}
public boolean isError() {
return problem.isError();
}
public String getFileName() {
return new String(problem.getOriginatingFileName());
}
public int getStartLine() {
return problem.getSourceLineNumber();
}
public int getStartColumn() {
return problem.getSourceStart();
}
public int getEndLine() {
return getStartLine();
}
public int getEndColumn() {
return problem.getSourceEnd();
}
public String getMessage() {
return problem.getMessage();
}
public String toString() {
final StringBuffer sb = new StringBuffer();
sb.append(getFileName()).append(" (");
sb.append(getStartLine());
sb.append(":");
sb.append(getStartColumn());
sb.append(") : ");
sb.append(getMessage());
return sb.toString();
}
public int getId() {
return problem.getID();
}
}
@@ -1,272 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.compilers.eclipse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.util.classloader.compilers.JavaCompiler;
import org.apache.struts2.util.classloader.problems.CompilationProblemHandler;
import org.apache.struts2.util.classloader.readers.ResourceReader;
import org.apache.struts2.util.classloader.stores.ResourceStore;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
import org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
public final class EclipseJavaCompiler implements JavaCompiler {
private final static Log log = LogFactory.getLog(EclipseJavaCompiler.class);
private final EclipseJavaCompilerSettings settings;
public EclipseJavaCompiler() {
this(new EclipseJavaCompilerSettings());
}
public EclipseJavaCompiler(final EclipseJavaCompilerSettings pSettings) {
settings = pSettings;
}
final class CompilationUnit implements ICompilationUnit {
final private String clazzName;
final private String fileName;
final private char[] typeName;
final private char[][] packageName;
final private ResourceReader reader;
CompilationUnit(final ResourceReader pReader, final String pClazzName) {
reader = pReader;
clazzName = pClazzName;
fileName = StringUtils.replaceChars(clazzName, '.', '/') + ".java";
int dot = clazzName.lastIndexOf('.');
if (dot > 0) {
typeName = clazzName.substring(dot + 1).toCharArray();
} else {
typeName = clazzName.toCharArray();
}
final StringTokenizer izer = new StringTokenizer(clazzName, ".");
packageName = new char[izer.countTokens() - 1][];
for (int i = 0; i < packageName.length; i++) {
packageName[i] = izer.nextToken().toCharArray();
}
}
public char[] getFileName() {
return fileName.toCharArray();
}
public char[] getContents() {
return reader.getContent(fileName);
}
public char[] getMainTypeName() {
return typeName;
}
public char[][] getPackageName() {
return packageName;
}
}
public void compile(final String[] pClazzNames, final ResourceReader pReader,
final ResourceStore pStore, final CompilationProblemHandler pProblemHandler) {
final Map settingsMap = settings.getMap();
final Set clazzIndex = new HashSet();
ICompilationUnit[] compilationUnits = new ICompilationUnit[pClazzNames.length];
for (int i = 0; i < compilationUnits.length; i++) {
final String clazzName = pClazzNames[i];
compilationUnits[i] = new CompilationUnit(pReader, clazzName);
clazzIndex.add(clazzName);
log.debug("compiling " + clazzName);
}
final IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.proceedWithAllProblems();
final IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault());
final INameEnvironment nameEnvironment = new INameEnvironment() {
public NameEnvironmentAnswer findType(final char[][] compoundTypeName) {
final StringBuffer result = new StringBuffer();
for (int i = 0; i < compoundTypeName.length; i++) {
if (i != 0) {
result.append('.');
}
result.append(compoundTypeName[i]);
}
return findType(result.toString());
}
public NameEnvironmentAnswer findType(final char[] typeName, final char[][] packageName) {
final StringBuffer result = new StringBuffer();
for (int i = 0; i < packageName.length; i++) {
result.append(packageName[i]);
result.append('.');
}
result.append(typeName);
return findType(result.toString());
}
private NameEnvironmentAnswer findType(final String clazzName) {
byte[] clazzBytes = pStore.read(clazzName);
if (clazzBytes != null) {
// log.debug("loading from store " + clazzName);
final char[] fileName = clazzName.toCharArray();
try {
final ClassFileReader classFileReader = new ClassFileReader(clazzBytes, fileName, true);
return new NameEnvironmentAnswer(classFileReader, null);
} catch (final ClassFormatException e) {
log.error("wrong class format", e);
}
} else {
if (pReader.isAvailable(clazzName.replace('.', '/') + ".java")) {
log.debug("compile " + clazzName);
ICompilationUnit compilationUnit = new CompilationUnit(pReader, clazzName);
return new NameEnvironmentAnswer(compilationUnit, null);
}
final String resourceName = clazzName.replace('.', '/') + ".class";
final InputStream is = this.getClass().getClassLoader().getResourceAsStream(resourceName);
if (is != null) {
final byte[] buffer = new byte[8192];
final ByteArrayOutputStream baos = new ByteArrayOutputStream(buffer.length);
int count;
try {
while ((count = is.read(buffer, 0, buffer.length)) > 0) {
baos.write(buffer, 0, count);
}
baos.flush();
clazzBytes = baos.toByteArray();
final char[] fileName = clazzName.toCharArray();
ClassFileReader classFileReader =
new ClassFileReader(clazzBytes, fileName, true);
return new NameEnvironmentAnswer(classFileReader, null);
} catch (final IOException e) {
log.error("could not read class", e);
} catch (final ClassFormatException e) {
log.error("wrong class format", e);
} finally {
try {
baos.close();
} catch (final IOException oe) {
log.error("could not close output stream", oe);
}
try {
is.close();
} catch (final IOException ie) {
log.error("could not close input stream", ie);
}
}
}
}
return null;
}
private boolean isPackage(final String clazzName) {
final String resourceName = clazzName.replace('.', '/') + ".class";
final URL resource = this.getClass().getClassLoader().getResource(resourceName);
return resource == null;
}
public boolean isPackage(char[][] parentPackageName, char[] packageName) {
final StringBuffer result = new StringBuffer();
if (parentPackageName != null) {
for (int i = 0; i < parentPackageName.length; i++) {
if (i != 0) {
result.append('.');
}
result.append(parentPackageName[i]);
}
}
if (Character.isUpperCase(packageName[0])) {
return false;
}
if (parentPackageName != null && parentPackageName.length > 0) {
result.append('.');
}
result.append(packageName);
return isPackage(result.toString());
}
public void cleanup() {
}
};
final ICompilerRequestor compilerRequestor = new ICompilerRequestor() {
public void acceptResult(CompilationResult result) {
if (result.hasProblems()) {
if (pProblemHandler != null) {
final IProblem[] problems = result.getProblems();
for (int i = 0; i < problems.length; i++) {
final IProblem problem = problems[i];
pProblemHandler.handle(new EclipseCompilationProblem(problem));
}
}
}
if (!result.hasErrors()) {
final ClassFile[] clazzFiles = result.getClassFiles();
for (int i = 0; i < clazzFiles.length; i++) {
final ClassFile clazzFile = clazzFiles[i];
final char[][] compoundName = clazzFile.getCompoundName();
final StringBuffer clazzName = new StringBuffer();
for (int j = 0; j < compoundName.length; j++) {
if (j != 0) {
clazzName.append('.');
}
clazzName.append(compoundName[j]);
}
pStore.write(clazzName.toString(), clazzFile.getBytes());
}
}
}
};
pProblemHandler.onStart();
try {
final Compiler compiler =
new Compiler(nameEnvironment, policy, settingsMap, compilerRequestor, problemFactory);
compiler.compile(compilationUnits);
} finally {
pProblemHandler.onStop();
}
}
}
@@ -1,45 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.compilers.eclipse;
import java.util.HashMap;
import java.util.Map;
import org.apache.struts2.util.classloader.compilers.JavaCompilerSettings;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
public class EclipseJavaCompilerSettings implements JavaCompilerSettings {
private final Map map = new HashMap();
public EclipseJavaCompilerSettings() {
map.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
map.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE);
map.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.GENERATE);
map.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE);
map.put(CompilerOptions.OPTION_ReportUnusedImport, CompilerOptions.IGNORE);
map.put(CompilerOptions.OPTION_Encoding, "UTF-8");
map.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
map.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
map.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
}
public Map getMap() {
return map;
}
}
@@ -1,168 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.listeners;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.util.classloader.ReloadingClassLoader;
import org.apache.struts2.util.classloader.compilers.JavaCompiler;
import org.apache.struts2.util.classloader.monitor.FilesystemAlterationListener;
import org.apache.struts2.util.classloader.problems.CompilationProblem;
import org.apache.struts2.util.classloader.problems.ConsoleCompilationProblemHandler;
import org.apache.struts2.util.classloader.problems.DefaultCompilationProblemHandler;
import org.apache.struts2.util.classloader.readers.ResourceReader;
import org.apache.struts2.util.classloader.stores.TransactionalResourceStore;
public class CompilingListener implements FilesystemAlterationListener {
private final static Log log = LogFactory.getLog(CompilingListener.class);
private final Collection created = new ArrayList();
private final Collection changed = new ArrayList();
private final Collection deleted = new ArrayList();
File pRepository;
private final JavaCompiler compiler;
private final ResourceReader reader;
private final TransactionalResourceStore transactionalStore;
private final DefaultCompilationProblemHandler problemHandler = new ConsoleCompilationProblemHandler();
public CompilingListener(
final ResourceReader pReader,
final JavaCompiler pCompiler,
final TransactionalResourceStore pTransactionalStore
) {
compiler = pCompiler;
reader = pReader;
transactionalStore = pTransactionalStore;
}
public DefaultCompilationProblemHandler getCompilationProblemHandler() {
return problemHandler;
}
public void onStart(final File pRepository) {
this.pRepository = pRepository;
created.clear();
changed.clear();
deleted.clear();
transactionalStore.onStart();
}
public void onStop(final File pRepository) {
this.pRepository = pRepository;
log.debug("resources " +
created.size() + " created, " +
changed.size() + " changed, " +
deleted.size() + " deleted");
boolean reload = false;
if (deleted.size() > 0) {
for (Iterator it = deleted.iterator(); it.hasNext();) {
final File file = (File) it.next();
transactionalStore.remove(ReloadingClassLoader.clazzName(pRepository, file));
}
reload = true;
}
final Collection compileables = new ArrayList();
compileables.addAll(created);
compileables.addAll(changed);
final String[] clazzes = new String[compileables.size()];
if (compileables.size() > 0) {
int i = 0;
for (Iterator it = compileables.iterator(); it.hasNext();) {
final File file = (File) it.next();
clazzes[i] = ReloadingClassLoader.clazzName(pRepository, file);
//log.debug(clazzes[i]);
i++;
}
compiler.compile(
clazzes,
reader,
transactionalStore,
problemHandler
);
final CompilationProblem[] errors = problemHandler.getErrors();
final CompilationProblem[] warnings = problemHandler.getWarnings();
log.debug(
errors.length + " errors, " +
warnings.length + " warnings"
);
if (errors.length > 0) {
for (int j = 0; j < clazzes.length; j++) {
transactionalStore.remove(clazzes[j]);
}
}
reload = true;
}
transactionalStore.onStop();
if (reload) {
reload();
}
}
public void onCreateFile(final File file) {
if (file.getName().endsWith(".java")) {
created.add(file);
}
}
public void onChangeFile(final File file) {
if (file.getName().endsWith(".java")) {
changed.add(file);
}
}
public void onDeleteFile(final File file) {
if (file.getName().endsWith(".java")) {
deleted.add(file);
}
}
public void onCreateDirectory(final File file) {
}
public void onChangeDirectory(final File file) {
}
public void onDeleteDirectory(final File file) {
}
protected void reload() {
log.debug("reload");
}
}
@@ -1,130 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.listeners;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.util.classloader.monitor.FilesystemAlterationListener;
import org.apache.struts2.util.classloader.stores.ResourceStore;
public class ReloadingListener implements FilesystemAlterationListener {
private final static Log log = LogFactory.getLog(ReloadingListener.class);
private final Collection created = new ArrayList();
private final Collection changed = new ArrayList();
private final Collection deleted = new ArrayList();
private final ResourceStore store;
public ReloadingListener(final ResourceStore pStore) {
store = pStore;
}
public void onStart(final File repository) {
created.clear();
changed.clear();
deleted.clear();
}
public void onStop(final File pRepository) {
boolean reload = false;
log.debug("created:" + created.size()
+ " changed:" + changed.size()
+ " deleted:" + deleted.size());
if (deleted.size() > 0) {
for (Iterator it = deleted.iterator(); it.hasNext();) {
final File file = (File) it.next();
store.remove(org.apache.struts2.util.classloader.ReloadingClassLoader.clazzName(pRepository, file));
}
reload = true;
}
if (created.size() > 0) {
for (Iterator it = created.iterator(); it.hasNext();) {
final File file = (File) it.next();
try {
final byte[] bytes = IOUtils.toByteArray(new FileReader(file));
store.write(org.apache.struts2.util.classloader.ReloadingClassLoader.clazzName(pRepository, file), bytes);
} catch (final Exception e) {
log.error("could not load " + file, e);
}
}
}
if (changed.size() > 0) {
for (Iterator it = changed.iterator(); it.hasNext();) {
final File file = (File) it.next();
try {
final byte[] bytes = IOUtils.toByteArray(new FileReader(file));
store.write(org.apache.struts2.util.classloader.ReloadingClassLoader.clazzName(pRepository, file), bytes);
} catch (final Exception e) {
log.error("could not load " + file, e);
}
}
reload = true;
}
notifyOfCheck(reload);
}
public void onCreateFile(final File file) {
if (file.getName().endsWith(".class")) {
created.add(file);
}
}
public void onChangeFile(final File file) {
if (file.getName().endsWith(".class")) {
changed.add(file);
}
}
public void onDeleteFile(final File file) {
if (file.getName().endsWith(".class")) {
deleted.add(file);
}
}
public void onCreateDirectory(final File file) {
}
public void onChangeDirectory(final File file) {
}
public void onDeleteDirectory(final File file) {
}
protected void notifyOfCheck(final boolean pReload) {
if (pReload) {
log.debug("reload required");
} else {
log.debug("no reload required");
}
}
}
@@ -1,40 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.monitor;
import java.io.File;
/**
*/
public interface FilesystemAlterationListener {
void onStart(final File repository);
void onCreateFile(final File file);
void onChangeFile(final File file);
void onDeleteFile(final File file);
void onCreateDirectory(final File dir);
void onChangeDirectory(final File dir);
void onDeleteDirectory(final File dir);
void onStop(final File repository);
}
@@ -1,412 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.monitor;
import java.io.File;
import java.io.FileFilter;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections.MultiHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.util.classloader.utils.ThreadUtils;
/**
*/
public final class FilesystemAlterationMonitor implements Runnable {
private final static Log log = LogFactory.getLog(FilesystemAlterationMonitor.class);
public class Entry {
private final File root;
private final File file;
private long lastModified;
private Set paths = new HashSet();
private Set childs = new HashSet();
private final boolean isDirectory;
public Entry(final File pRoot, final File pFile) {
root = pRoot;
file = pFile;
lastModified = -1;
isDirectory = file.isDirectory();
}
public boolean hasChanged() {
final long modified = file.lastModified();
return modified != lastModified;
}
public boolean isDelected() {
return !file.exists();
}
public boolean isDirectory() {
return isDirectory;
}
public Entry[] getChilds() {
final Entry[] r = new Entry[childs.size()];
childs.toArray(r);
return r;
}
private FileFilter getFileFilter() {
return new FileFilter() {
public boolean accept(final File pathname) {
final String p = pathname.getAbsolutePath();
return !paths.contains(p);
}
};
}
public Entry[] getNonChilds() {
final File[] newFiles = file.listFiles(getFileFilter());
final Entry[] r = new Entry[newFiles.length];
for (int i = 0; i < newFiles.length; i++) {
r[i] = new Entry(root, newFiles[i]);
}
return r;
}
public void add(final Entry entry) {
childs.add(entry);
paths.add(entry.toString());
onCreate(root, entry);
}
private void deleteChilds() {
final Entry[] childs = this.getChilds();
for (int i = 0; i < childs.length; i++) {
final Entry child = childs[i];
delete(child);
}
}
public void delete(final Entry entry) {
childs.remove(entry);
paths.remove(entry.toString());
entry.deleteChilds();
onDelete(root, entry);
}
public File getFile() {
return file;
}
public void markNotChanged() {
lastModified = file.lastModified();
}
public String toString() {
return file.getAbsolutePath();
}
}
private Map listeners = new MultiHashMap();
private Map directories = new MultiHashMap();
private Map entries = new HashMap();
private final Object mutexListeners = new Object();
private final Object mutexRunning = new Object();
private long delay = 3000;
private boolean running = true;
public FilesystemAlterationMonitor() {
}
public void stop() {
synchronized (mutexRunning) {
running = false;
}
}
public void setInterval(final long pDelay) {
delay = pDelay;
}
public void addListener(final FilesystemAlterationListener listener, final File directory) {
synchronized (mutexListeners) {
// listerner -> dir1, dir2, dir3
final MultiHashMap newListeners = new MultiHashMap(listeners);
newListeners.put(listener, directory);
listeners = newListeners;
// directory -> listener1, listener2, listener3
final MultiHashMap newDirectories = new MultiHashMap(directories);
newDirectories.put(directory, listener);
directories = newDirectories;
}
}
public void removeListener(final FilesystemAlterationListener listener) {
synchronized (mutexListeners) {
// listerner -> dir1, dir2, dir3
final MultiHashMap newListeners = new MultiHashMap(listeners);
Collection d = (Collection) newListeners.remove(listener);
listeners = newListeners;
if (d != null) {
// directory -> listener1, listener2, listener3
final MultiHashMap newDirectories = new MultiHashMap(directories);
for (Iterator it = d.iterator(); it.hasNext();) {
newDirectories.remove(it.next());
entries.remove(d);
}
directories = newDirectories;
}
}
}
private void onStart(final File root) {
log.debug("start checking " + root);
Map directories;
synchronized (mutexListeners) {
directories = this.directories;
}
final Collection l = (Collection) directories.get(root);
if (l != null) {
for (Iterator it = l.iterator(); it.hasNext();) {
final FilesystemAlterationListener listener = (FilesystemAlterationListener) it.next();
listener.onStart(root);
}
}
}
private void onStop(final File root) {
log.debug("stop checking " + root);
Map directories;
synchronized (mutexListeners) {
directories = this.directories;
}
final Collection l = (Collection) directories.get(root);
if (l != null) {
for (Iterator it = l.iterator(); it.hasNext();) {
final FilesystemAlterationListener listener = (FilesystemAlterationListener) it.next();
listener.onStop(root);
}
}
}
private void onCreate(final File root, final Entry entry) {
log.debug("created " + ((entry.isDirectory()) ? "dir " : "file ") + entry);
Map directories;
synchronized (mutexListeners) {
directories = this.directories;
}
final Collection l = (Collection) directories.get(root);
if (l != null) {
if (entry.isDirectory()) {
for (Iterator it = l.iterator(); it.hasNext();) {
final FilesystemAlterationListener listener = (FilesystemAlterationListener) it.next();
listener.onCreateDirectory(entry.getFile());
}
} else {
for (Iterator it = l.iterator(); it.hasNext();) {
final FilesystemAlterationListener listener = (FilesystemAlterationListener) it.next();
listener.onCreateFile(entry.getFile());
}
}
}
entry.markNotChanged();
}
private void onChange(final File root, final Entry entry) {
log.debug("changed " + ((entry.isDirectory()) ? "dir " : "file ") + entry);
Map directories;
synchronized (mutexListeners) {
directories = this.directories;
}
final Collection l = (Collection) directories.get(root);
if (l != null) {
if (entry.isDirectory()) {
for (Iterator it = l.iterator(); it.hasNext();) {
final FilesystemAlterationListener listener = (FilesystemAlterationListener) it.next();
listener.onChangeDirectory(entry.getFile());
}
} else {
for (Iterator it = l.iterator(); it.hasNext();) {
final FilesystemAlterationListener listener = (FilesystemAlterationListener) it.next();
listener.onChangeFile(entry.getFile());
}
}
}
entry.markNotChanged();
}
private void onDelete(final File root, final Entry entry) {
log.debug("deleted " + ((entry.isDirectory()) ? "dir " : "file ") + entry);
Map directories;
synchronized (mutexListeners) {
directories = this.directories;
}
final Collection l = (Collection) directories.get(root);
if (l != null) {
if (entry.isDirectory()) {
for (Iterator it = l.iterator(); it.hasNext();) {
final FilesystemAlterationListener listener = (FilesystemAlterationListener) it.next();
listener.onDeleteDirectory(entry.getFile());
}
} else {
for (Iterator it = l.iterator(); it.hasNext();) {
final FilesystemAlterationListener listener = (FilesystemAlterationListener) it.next();
listener.onDeleteFile(entry.getFile());
}
}
}
entry.markNotChanged();
}
private void check(final File root, final Entry entry, final boolean create) {
//log.debug("checking " + entry);
if (entry.isDirectory()) {
final Entry[] currentChilds = entry.getChilds();
if (entry.hasChanged() || create) {
//log.debug(entry + " has changed");
if (!create) {
onChange(root, entry);
for (int i = 0; i < currentChilds.length; i++) {
final Entry child = currentChilds[i];
if (child.isDelected()) {
entry.delete(child);
currentChilds[i] = null;
}
}
}
final Entry[] newChilds = entry.getNonChilds();
for (int i = 0; i < newChilds.length; i++) {
final Entry child = newChilds[i];
entry.add(child);
}
if (!create) {
for (int i = 0; i < currentChilds.length; i++) {
final Entry child = currentChilds[i];
if (child != null) {
check(root, child, false);
}
}
}
for (int i = 0; i < newChilds.length; i++) {
final Entry child = newChilds[i];
check(root, child, true);
}
} else {
//log.debug(entry + " has not changed");
for (int i = 0; i < currentChilds.length; i++) {
final Entry child = currentChilds[i];
check(root, child, false);
}
}
} else {
if (entry.isDelected()) {
onDelete(root, entry);
} else if (entry.hasChanged()) {
onChange(root, entry);
}
}
}
public void run() {
log.info("fam running");
while (true) {
synchronized (mutexRunning) {
if (!running) {
break;
}
}
doRun();
ThreadUtils.sleep(delay);
}
log.info("fam exiting");
}
public void doRun() {
Map directories;
synchronized (mutexListeners) {
directories = this.directories;
}
for (Iterator it = directories.keySet().iterator(); it.hasNext();) {
final File directory = (File) it.next();
if (directory.exists()) {
onStart(directory);
Entry root;
synchronized (mutexListeners) {
root = (Entry) entries.get(directory);
if (root == null) {
root = new Entry(directory, directory);
entries.put(directory, root);
}
}
check(directory, root, false);
onStop(directory);
}
}
}
}
@@ -1,36 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.problems;
public interface CompilationProblem {
boolean isError();
String getFileName();
int getStartLine();
int getStartColumn();
int getEndLine();
int getEndColumn();
String getMessage();
}
@@ -1,29 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.problems;
/**
*/
public interface CompilationProblemHandler {
void onStart();
void handle(final CompilationProblem pProblem);
void onStop();
}
@@ -1,31 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.problems;
/**
*/
public final class ConsoleCompilationProblemHandler extends DefaultCompilationProblemHandler {
public void handle(final CompilationProblem pProblem) {
if (pProblem.isError()) {
System.err.println("error:" + pProblem);
} else {
System.err.println("warning:" + pProblem);
}
}
}
@@ -1,56 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.problems;
import java.util.ArrayList;
import java.util.Collection;
public class DefaultCompilationProblemHandler implements CompilationProblemHandler {
final Collection errors = new ArrayList();
final Collection warnings = new ArrayList();
public void onStart() {
errors.clear();
warnings.clear();
}
public void handle(final CompilationProblem pProblem) {
if (pProblem.isError()) {
errors.add(pProblem);
} else {
warnings.add(pProblem);
}
}
public void onStop() {
}
public CompilationProblem[] getErrors() {
final CompilationProblem[] result = new CompilationProblem[errors.size()];
errors.toArray(result);
return result;
}
public CompilationProblem[] getWarnings() {
final CompilationProblem[] result = new CompilationProblem[warnings.size()];
warnings.toArray(result);
return result;
}
}
@@ -1,36 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.problems;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*/
public final class LogCompilationProblemHandler extends DefaultCompilationProblemHandler {
private final static Log log = LogFactory.getLog(ConsoleCompilationProblemHandler.class);
public void handle(final CompilationProblem pProblem) {
if (pProblem.isError()) {
log.debug("error:" + pProblem);
} else {
log.debug("warning:" + pProblem);
}
}
}
@@ -1,46 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.readers;
import java.io.File;
import org.apache.commons.io.FileUtils;
/**
*/
public final class FileResourceReader implements ResourceReader {
private final File base;
public FileResourceReader(final File pBase) {
base = pBase;
}
public boolean isAvailable(String filename) {
return new File(base, filename).exists();
}
public char[] getContent(final String fileName) {
try {
return FileUtils.readFileToString(
new File(base, fileName), "UTF-8").toCharArray();
} catch (Exception e) {
}
return null;
}
}
@@ -1,27 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.readers;
/**
*/
public interface ResourceReader {
boolean isAvailable(final String filename);
char[] getContent(final String fileName);
}
@@ -1,94 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.stores;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
/**
*/
public final class FileResourceStore implements ResourceStore {
private final File root;
public FileResourceStore(final File pFile) {
root = pFile;
}
public byte[] read(final String resourceName) {
InputStream is = null;
try {
is = new FileInputStream(getFile(resourceName));
final byte[] data = IOUtils.toByteArray(is);
return data;
} catch (FileNotFoundException e) {
} catch (IOException e) {
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
}
return null;
}
public void write(final String resourceName, final byte[] clazzData) {
OutputStream os = null;
try {
final File file = getFile(resourceName);
final File parent = file.getParentFile();
if (!parent.exists()) {
if (!parent.mkdirs()) {
throw new IOException("could not create" + parent);
}
}
os = new FileOutputStream(file);
os.write(clazzData);
} catch (FileNotFoundException e) {
} catch (IOException e) {
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
}
}
}
}
public void remove(final String pResourceName) {
getFile(pResourceName).delete();
}
private File getFile(final String pResourceName) {
final String fileName = pResourceName.replace('.', File.separatorChar) + ".class";
return new File(root, fileName);
}
}
@@ -1,52 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.stores;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*/
public final class MemoryResourceStore implements ResourceStore {
private final static Log log = LogFactory.getLog(MemoryResourceStore.class);
private final Map store = new HashMap();
public byte[] read(final String resourceName) {
return (byte[]) store.get(resourceName);
}
public void write(final String resourceName, final byte[] clazzData) {
log.debug("storing resource " + resourceName + "(" + clazzData.length + ")");
store.put(resourceName, clazzData);
}
public void remove(final String resourceName) {
log.debug("removing resource " + resourceName);
store.remove(resourceName);
}
public String toString() {
return store.keySet().toString();
}
}
@@ -1,29 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.stores;
/**
*/
public interface ResourceStore {
void write(final String resourceName, final byte[] resourceData);
byte[] read(final String resourceName);
void remove(final String resourceName);
}
@@ -1,83 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.stores;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*/
public final class ResourceStoreClassLoader extends ClassLoader {
private final static Log log = LogFactory.getLog(ResourceStoreClassLoader.class);
private final ResourceStore store;
public ResourceStoreClassLoader(final ClassLoader pParent, final ResourceStore pStore) {
super(pParent);
store = pStore;
}
private Class fastFindClass(final String name) {
final byte[] clazzBytes = store.read(name);
if (clazzBytes != null) {
log.debug("found class " + name + " (" + clazzBytes.length + " bytes)");
return defineClass(name, clazzBytes, 0, clazzBytes.length);
}
return null;
}
protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
Class clazz = findLoadedClass(name);
if (clazz == null) {
clazz = fastFindClass(name);
if (clazz == null) {
final ClassLoader parent = getParent();
if (parent != null) {
clazz = parent.loadClass(name);
log.debug("loaded from parent: " + name);
} else {
throw new ClassNotFoundException(name);
}
} else {
log.debug("loaded from store: " + name);
}
}
if (resolve) {
resolveClass(clazz);
}
return clazz;
}
protected Class findClass(final String name) throws ClassNotFoundException {
final Class clazz = fastFindClass(name);
if (clazz == null) {
throw new ClassNotFoundException(name);
}
return clazz;
}
}
@@ -1,50 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.stores;
/**
*/
public abstract class TransactionalResourceStore implements ResourceStore {
private final ResourceStore store;
public TransactionalResourceStore(final ResourceStore pStore) {
store = pStore;
}
public abstract void onStart();
public abstract void onStop();
public byte[] read(String resourceName) {
return store.read(resourceName);
}
public void remove(String resourceName) {
store.remove(resourceName);
}
public void write(String resourceName, byte[] resourceData) {
store.write(resourceName, resourceData);
}
public String toString() {
return store.toString();
}
}
@@ -1,30 +0,0 @@
/*
* $Id$
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed 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.struts2.util.classloader.utils;
public final class ThreadUtils {
public static void sleep(final long pDelay) {
try {
Thread.sleep(pDelay);
} catch (final InterruptedException e) {
}
}
}