Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during
compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based
@AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step.
This library is a superset of AspectJ weaver and hence also of AspectJ runtime.
/* *******************************************************************
* Copyright (c) 2003 Contributors.
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v 2.0
* which accompanies this distribution and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
*
* Contributors:
* Mik Kersten initial implementation
* Andy Clement incremental support and switch on/off state
* ******************************************************************/
package org.aspectj.asm;
import java.io.BufferedWriter;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.aspectj.asm.internal.AspectJElementHierarchy;
import org.aspectj.asm.internal.HandleProviderDelimiter;
import org.aspectj.asm.internal.JDTLikeHandleProvider;
import org.aspectj.asm.internal.RelationshipMap;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.util.IStructureModel;
/**
* The Abstract Structure Model (ASM) represents the containment hierarchy and crosscutting structure map for AspectJ programs. It
* is used by IDE views such as the document outline, and by other tools such as ajdoc to show both AspectJ declarations and
* crosscutting links, such as which advice affects which join point shadows.
*
* @author Mik Kersten
* @author Andy Clement
*/
public class AsmManager implements IStructureModel {
// For testing ONLY
public static boolean recordingLastActiveStructureModel = true;
public static AsmManager lastActiveStructureModel;
public static boolean forceSingletonBehaviour = false;
// SECRETAPI asc pull the secret options together into a system API you lazy fool
public static boolean attemptIncrementalModelRepairs = false;
// Dumping the model is expensive
public static boolean dumpModelPostBuild = false;
// For offline debugging, you can now ask for the AsmManager to
// dump the model - see the method setReporting()
private static boolean dumpModel = false;
private static boolean dumpRelationships = false;
private static boolean dumpDeltaProcessing = false;
private static IModelFilter modelFilter = null;
private static String dumpFilename = "";
private static boolean reporting = false;
private static boolean completingTypeBindings = false;
private final List structureListeners = new ArrayList<>();
// The model is 'manipulated' by the AjBuildManager.setupModel() code which
// trashes all the
// fields when setting up a new model for a batch build.
// Due to the requirements of incremental compilation we need to tie some of
// the info
// below to the AjState for a compilation and recover it if switching
// between projects.
protected IHierarchy hierarchy;
/*
* Map from String > String - it maps absolute paths for inpath dirs/jars to workspace relative paths suitable for handle
* inclusion
*/
protected Map inpathMap;
private IRelationshipMap mapper;
private IElementHandleProvider handleProvider;
private final CanonicalFilePathMap canonicalFilePathMap = new CanonicalFilePathMap();
// Record the Set for which the model has been modified during the
// last incremental build
private final Set lastBuildChanges = new HashSet<>();
// Record the Set of aspects that wove the files listed in lastBuildChanges
final Set aspectsWeavingInLastBuild = new HashSet<>();
// static {
// setReporting("c:/model.nfo",true,true,true,true);
// }
private AsmManager() {
}
public static AsmManager createNewStructureModel(Map inpathMap) {
if (forceSingletonBehaviour && lastActiveStructureModel != null) {
return lastActiveStructureModel;
}
AsmManager asm = new AsmManager();
asm.inpathMap = inpathMap;
asm.hierarchy = new AspectJElementHierarchy(asm);
asm.mapper = new RelationshipMap();
asm.handleProvider = new JDTLikeHandleProvider(asm);
// call initialize on the handleProvider when we create a new ASM
// to give handleProviders the chance to reset any state
asm.handleProvider.initialize();
asm.resetDeltaProcessing();
setLastActiveStructureModel(asm);
return asm;
}
public IHierarchy getHierarchy() {
return hierarchy;
}
public IRelationshipMap getRelationshipMap() {
return mapper;
}
public void fireModelUpdated() {
notifyListeners();
if (dumpModelPostBuild && hierarchy.getConfigFile() != null) {
writeStructureModel(hierarchy.getConfigFile());
}
}
/**
* Constructs map each time it's called.
*/
public HashMap> getInlineAnnotations(String sourceFile, boolean showSubMember,
boolean showMemberAndType) {
if (!hierarchy.isValid()) {
return null;
}
HashMap> annotations = new HashMap<>();
IProgramElement node = hierarchy.findElementForSourceFile(sourceFile);
if (node == IHierarchy.NO_STRUCTURE) {
return null;
} else {
IProgramElement fileNode = node;
List peNodes = new ArrayList<>();
getAllStructureChildren(fileNode, peNodes, showSubMember, showMemberAndType);
for (IProgramElement peNode : peNodes) {
List entries = new ArrayList<>();
entries.add(peNode);
ISourceLocation sourceLoc = peNode.getSourceLocation();
if (null != sourceLoc) {
Integer hash = sourceLoc.getLine();
List existingEntry = annotations.get(hash);
if (existingEntry != null) {
entries.addAll(existingEntry);
}
annotations.put(hash, entries);
}
}
return annotations;
}
}
private void getAllStructureChildren(IProgramElement node, List result, boolean showSubMember,
boolean showMemberAndType) {
List children = node.getChildren();
if (node.getChildren() == null) {
return;
}
for (IProgramElement next : children) {
List rels = mapper.get(next);
if (next != null
&& ((next.getKind() == IProgramElement.Kind.CODE && showSubMember) || (next.getKind() != IProgramElement.Kind.CODE && showMemberAndType))
&& rels != null && rels.size() > 0) {
result.add(next);
}
getAllStructureChildren(next, result, showSubMember, showMemberAndType);
}
}
public void addListener(IHierarchyListener listener) {
structureListeners.add(listener);
}
public void removeStructureListener(IHierarchyListener listener) {
structureListeners.remove(listener);
}
// this shouldn't be needed - but none of the people that add listeners
// in the test suite ever remove them. AMC added this to be called in
// setup() so that the test cases would cease leaking listeners and go
// back to executing at a reasonable speed.
public void removeAllListeners() {
structureListeners.clear();
}
private void notifyListeners() {
for (IHierarchyListener listener : structureListeners) {
listener.elementsUpdated(hierarchy);
}
}
public IElementHandleProvider getHandleProvider() {
return handleProvider;
}
public void setHandleProvider(IElementHandleProvider handleProvider) {
this.handleProvider = handleProvider;
}
public void writeStructureModel(String configFilePath) {
try {
String filePath = genExternFilePath(configFilePath);
FileOutputStream fos = new FileOutputStream(filePath);
ObjectOutputStream s = new ObjectOutputStream(fos);
s.writeObject(hierarchy); // Store the program element tree
s.writeObject(mapper); // Store the relationships
s.flush();
fos.flush();
fos.close();
s.close();
} catch (IOException e) {
// System.err.println("AsmManager: Unable to write structure model: "
// +configFilePath+" because of:");
// e.printStackTrace();
}
}
/**
* @param configFilePath path to an ".lst" file
*/
public void readStructureModel(String configFilePath) {
boolean hierarchyReadOK = false;
try {
if (configFilePath == null) {
hierarchy.setRoot(IHierarchy.NO_STRUCTURE);
} else {
String filePath = genExternFilePath(configFilePath);
FileInputStream in = new FileInputStream(filePath);
ObjectInputStream s = new ObjectInputStream(in);
hierarchy = (AspectJElementHierarchy) s.readObject();
((AspectJElementHierarchy) hierarchy).setAsmManager(this);
hierarchyReadOK = true;
mapper = (RelationshipMap) s.readObject();
s.close();
}
} catch (FileNotFoundException fnfe) {
// That is OK
hierarchy.setRoot(IHierarchy.NO_STRUCTURE);
} catch (EOFException eofe) {
// Might be an old format sym file that is missing its relationships
if (!hierarchyReadOK) {
System.err.println("AsmManager: Unable to read structure model: " + configFilePath + " because of:");
eofe.printStackTrace();
hierarchy.setRoot(IHierarchy.NO_STRUCTURE);
}
} catch (Exception e) {
// System.err.println("AsmManager: Unable to read structure model: "+
// configFilePath+" because of:");
// e.printStackTrace();
hierarchy.setRoot(IHierarchy.NO_STRUCTURE);
} finally {
notifyListeners();
}
}
private String genExternFilePath(String configFilePath) {
// sometimes don't have ".lst"
if (configFilePath.lastIndexOf(".lst") != -1) {
configFilePath = configFilePath.substring(0, configFilePath.lastIndexOf(".lst"));
}
return configFilePath + ".ajsym";
}
public String getCanonicalFilePath(File f) {
return canonicalFilePathMap.get(f);
}
public CanonicalFilePathMap getCanonicalFilePathMap() {
return canonicalFilePathMap;
}
private static class CanonicalFilePathMap {
private static final int MAX_SIZE = 4000;
private final Map pathMap = new HashMap<>(20);
// // guards to ensure correctness and liveness
// private boolean cacheInUse = false;
// private boolean stopRequested = false;
//
// private synchronized boolean isCacheInUse() {
// return cacheInUse;
// }
//
// private synchronized void setCacheInUse(boolean val) {
// cacheInUse = val;
// if (val) {
// notifyAll();
// }
// }
//
// private synchronized boolean isStopRequested() {
// return stopRequested;
// }
//
// private synchronized void requestStop() {
// stopRequested = true;
// }
//
// /**
// * Begin prepopulating the map by adding an entry from
// * file.getPath -> file.getCanonicalPath for each file in
// * the list. Do this on a background thread.
// * @param files
// */
// public void prepopulate(final List files) {
// stopRequested = false;
// setCacheInUse(false);
// if (pathMap.size() > MAX_SIZE) {
// pathMap.clear();
// }
// new Thread() {
// public void run() {
// System.out.println("Starting cache population: " +
// System.currentTimeMillis());
// Iterator it = files.iterator();
// while (!isStopRequested() && it.hasNext()) {
// File f = (File)it.next();
// if (pathMap.get(f.getPath()) == null) {
// // may reuse cache across compiles from ides...
// try {
// pathMap.put(f.getPath(),f.getCanonicalPath());
// } catch (IOException ex) {
// pathMap.put(f.getPath(),f.getPath());
// }
// }
// }
// System.out.println("Cached " + files.size());
// setCacheInUse(true);
// System.out.println("Cache populated: " + System.currentTimeMillis());
// }
// }.start();
// }
//
// /**
// * Stop pre-populating the cache - our customers are ready to use it.
// * If there are any cache misses from this point on, we'll populate
// the
// * cache as we go.
// * The handover is done this way to ensure that only one thread is
// ever
// * accessing the cache, and that we minimize synchronization.
// */
// public synchronized void handover() {
// if (!isCacheInUse()) {
// requestStop();
// try {
// while (!isCacheInUse()) wait();
// } catch (InterruptedException intEx) { } // just continue
// }
// }
public String get(File f) {
// if (!cacheInUse) { // unsynchronized test - should never be
// parallel
// // threads at this point
// throw new IllegalStateException(
// "Must take ownership of cache before using by calling " +
// "handover()");
// }
String ret = pathMap.get(f.getPath());
if (ret == null) {
try {
ret = f.getCanonicalPath();
} catch (IOException ioEx) {
ret = f.getPath();
}
pathMap.put(f.getPath(), ret);
if (pathMap.size() > MAX_SIZE) {
pathMap.clear();
}
}
return ret;
}
}
// SECRETAPI
public static void setReporting(String filename, boolean dModel, boolean dRels, boolean dDeltaProcessing, boolean deletefile) {
reporting = true;
dumpModel = dModel;
dumpRelationships = dRels;
dumpDeltaProcessing = dDeltaProcessing;
if (deletefile) {
new File(filename).delete();
}
dumpFilename = filename;
}
public static void setReporting(String filename, boolean dModel, boolean dRels, boolean dDeltaProcessing, boolean deletefile,
IModelFilter aFilter) {
setReporting(filename, dModel, dRels, dDeltaProcessing, deletefile);
modelFilter = aFilter;
}
public static boolean isReporting() {
return reporting;
}
public static void setDontReport() {
reporting = false;
dumpDeltaProcessing = false;
dumpModel = false;
dumpRelationships = false;
}
// NB. If the format of this report changes then the model tests
// (@see org.aspectj.systemtest.model.ModelTestCase) will fail in
// their comparison. The tests are assuming that both the model
// and relationship map are reported and as a consequence single
// testcases test that both the model and relationship map are correct.
public void reportModelInfo(String reasonForReport) {
if (!dumpModel && !dumpRelationships) {
return;
}
try {
FileWriter fw = new FileWriter(dumpFilename, true);
BufferedWriter bw = new BufferedWriter(fw);
if (dumpModel) {
bw.write("=== MODEL STATUS REPORT ========= " + reasonForReport + "\n");
dumptree(bw, hierarchy.getRoot(), 0);
bw.write("=== END OF MODEL REPORT =========\n");
}
if (dumpRelationships) {
bw.write("=== RELATIONSHIPS REPORT ========= " + reasonForReport + "\n");
dumprels(bw);
bw.write("=== END OF RELATIONSHIPS REPORT ==\n");
}
Properties p = summarizeModel().getProperties();
Enumeration