/* *******************************************************************
* Copyright (c) 1999-2001 Xerox Corporation,
* 2002 Palo Alto Research Center, Incorporated (PARC).
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* PARC initial implementation
* ******************************************************************/
package org.aspectj.ajdt.internal.core.builder;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.aspectj.asm.AsmManager;
import org.aspectj.asm.IProgramElement;
/**
* @author Mik Kersten
*/
public class EmacsStructureModelManager {
private static final String EXTERN_FILE_SUFFIX = ".ajesym";
public EmacsStructureModelManager() {
super();
}
public void externalizeModel(AsmManager model) {
if (!model.getHierarchy().isValid())
return;
try {
// Set fileSet = StructureModelManager.INSTANCE.getStructureModel().getFileMap().entrySet();
Set fileSet = model.getHierarchy().getFileMapEntrySet();
for (Iterator it = fileSet.iterator(); it.hasNext();) {
IProgramElement peNode = (IProgramElement) ((Map.Entry) it.next()).getValue();
dumpStructureToFile(peNode);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
// private void dumpStructureToFile(ProgramElementNode node) throws IOException {
// String sourceName = node.getSourceLocation().getSourceFilePath();
// String fileName = sourceName.substring(0, sourceName.lastIndexOf(".")) + EXTERN_FILE_SUFFIX;
// BufferedWriter writer = new BufferedWriter(new FileWriter(new File(fileName)));
// new SExpressionPrinter(writer).printDecls(node);
// writer.flush();
// }
private void dumpStructureToFile(IProgramElement node) throws IOException {
String s = node.getKind().toString();
if (!(s.equals(IProgramElement.Kind.FILE_ASPECTJ.toString()) || s.equals(IProgramElement.Kind.FILE_JAVA.toString()))) {
throw new IllegalArgumentException("externalize file, not " + node);
}
// source files have source locations
String sourceName = node.getSourceLocation().getSourceFile().getAbsolutePath();
String fileName = sourceName.substring(0, sourceName.lastIndexOf(".")) + EXTERN_FILE_SUFFIX;
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(new File(fileName)));
new SExpressionPrinter(writer).printDecls(node);
writer.flush();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
} // ignore
}
}
}
/**
* This class was not written in an OO style.
*/
private static class SExpressionPrinter {
private BufferedWriter writer = null;
public SExpressionPrinter(BufferedWriter writer) {
this.writer = writer;
}
private void printDecls(IProgramElement node) {
print("(");
for (Iterator it = node.getChildren().iterator(); it.hasNext();) {
// this ignores relations on the compile unit
Object nodeObject = it.next();
// throw new RuntimeException("unimplemented");
// if (nodeObject instanceof IProgramElement) {
IProgramElement child = (IProgramElement) nodeObject;
printDecl(child, true);
// }
// else if (nodeObject instanceof LinkNode) {
// LinkNode child = (LinkNode)nodeObject;
// printDecl(child.getProgramElementNode(), false);
// }
}
print(") ");
}
// private void printDecls(IRelationship node) {
// // for (Iterator it = node.getTargets().iterator(); it.hasNext(); ) {
// // // this ignores relations on the compile unit
// // Object nodeObject = it.next();
// // throw new RuntimeException("unimplemented");
// //// if (nodeObject instanceof LinkNode) {
// //// LinkNode child = (LinkNode)nodeObject;
// //// if (//!child.getProgramElementNode().getKind().equals("stmnt") &&
// //// !child.getProgramElementNode().getKind().equals("<undefined>")) {
// //// printDecl(child.getProgramElementNode(), false);
// ////// printDecl(child.getProgramElementNode(), false);
// //// }
// //// }
// // }
// }
/**
* @param structureNode can be a ProgramElementNode or a LinkNode
*/
private void printDecl(IProgramElement node, boolean recurse) {
if (node == null || node.getSourceLocation() == null)
return;
String kind = node.getKind().toString().toLowerCase();
print("(");
print("(" + node.getSourceLocation().getLine() + " . " + node.getSourceLocation().getColumn() + ") ");
print("(" + node.getSourceLocation().getLine() + " . " + node.getSourceLocation().getColumn() + ") ");
print(kind + " "); // 2
// HACK:
String displayName = node.toString().replace('\"', ' ');
print("\"" + displayName + "\" ");
if (node.getSourceLocation().getSourceFile().getAbsolutePath() != null) {
print("\"" + fixFilename(node.getSourceLocation().getSourceFile().getAbsolutePath()) + "\""); // 4
} else {
print("nil");
}
if (node.getName() != null) {
print("\"" + node.getDeclaringType() + "\" "); // 5
} else {
print("nil");
}
if (!recurse) {
print("nil");
print("nil");
print("nil");
} else {
print("(");
// if (node instanceof IProgramElement) {
// java.util.List relations = ((IProgramElement)node).getRelations();
// if (relations != null) {
// for (Iterator it = relations.iterator(); it.hasNext(); ) {
// IRelationship relNode = (IRelationship)it.next();
// if (relNode.getKind() == IRelationship.Kind.ADVICE ||
// relNode.getKind() == IRelationship.Kind.DECLARE) {
// printDecls(relNode); // 6
// }
// }
// }
// }
print(") ");
print("(");
print(") ");
print("(");
Iterator it3 = node.getChildren().iterator();
if (it3.hasNext()) {
while (it3.hasNext()) {
// this ignores relations on the compile unit
Object nodeObject = it3.next();
if (nodeObject instanceof IProgramElement) {
IProgramElement currNode = (IProgramElement) nodeObject;
if (// !currNode.isStmntKind() &&
!currNode.getKind().equals("<undefined>")) {
printDecl(currNode, true);
}
}
}
}
print(") ");
}
print(node.getKind().equals("class") ? "t " : "nil "); // 9
// print(node.getKind().equals("introduction") ? "t " : "nil "); // 10
print(node.getKind().equals("introduction") ? "nil " : "nil "); // 10
print("nil "); // 11
print("nil "); // 12
print(")");
}
String fixFilename(String filename) {
return subst("\\\\", "\\", filename);
}
private void print(String string) {
try {
writer.write(string + "\n");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
private String subst(String n, String o, String in) {
int pos = in.indexOf(o);
if (pos == -1)
return in;
return in.substring(0, pos) + n + subst(n, o, (in.substring(pos + o.length())));
}
// private void lose(Error e) {
// try {
// print("(ERROR \"" + e.toString() + "\")");
// }
// catch(Error ex) { }
// }
}
}