001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.instrumentation.core;
022:
023: import java.util.*;
024:
025: import com.db4o.instrumentation.util.*;
026:
027: import EDU.purdue.cs.bloat.cfg.*;
028: import EDU.purdue.cs.bloat.context.*;
029: import EDU.purdue.cs.bloat.editor.*;
030: import EDU.purdue.cs.bloat.reflect.*;
031:
032: public class BloatLoaderContext {
033: private ClassInfoLoader loader;
034: private EditorContext context;
035:
036: public BloatLoaderContext(ClassInfoLoader loader) {
037: this (loader, new CachingBloatContext(loader, new LinkedList(),
038: false));
039: }
040:
041: public BloatLoaderContext(ClassInfoLoader loader,
042: EditorContext context) {
043: this .loader = loader;
044: this .context = context;
045: }
046:
047: public FlowGraph flowGraph(String className, String methodName)
048: throws ClassNotFoundException {
049: return flowGraph(className, methodName, null);
050: }
051:
052: public FlowGraph flowGraph(String className, String methodName,
053: Type[] argTypes) throws ClassNotFoundException {
054: ClassEditor classEdit = classEditor(className);
055: return flowGraph(classEdit, methodName, argTypes);
056: }
057:
058: public FlowGraph flowGraph(ClassEditor classEdit,
059: String methodName, Type[] argTypes)
060: throws ClassNotFoundException {
061: MethodEditor method = method(classEdit, methodName, argTypes);
062: return method == null ? null : new FlowGraph(method);
063: }
064:
065: public MethodEditor method(ClassEditor classEdit,
066: String methodName, Type[] argTypes)
067: throws ClassNotFoundException {
068: ClassEditor clazz = classEdit;
069: while (clazz != null) {
070: MethodInfo[] methods = clazz.methods();
071: for (int methodIdx = 0; methodIdx < methods.length; methodIdx++) {
072: MethodInfo methodInfo = methods[methodIdx];
073: MethodEditor methodEdit = new MethodEditor(clazz,
074: methodInfo);
075: if (methodEdit.name().equals(methodName)
076: && signatureMatchesTypes(argTypes, methodEdit)) {
077: return methodEdit;
078: }
079: }
080: clazz = classEditor(clazz.super class());
081: }
082: return null;
083: }
084:
085: public ClassEditor classEditor(Type type)
086: throws ClassNotFoundException {
087: return type == null ? null : classEditor(BloatUtil
088: .normalizeClassName(type));
089: }
090:
091: private boolean signatureMatchesTypes(Type[] argTypes,
092: MethodEditor methodEdit) {
093: if (argTypes == null) {
094: return true;
095: }
096: Type[] sigTypes = methodEdit.paramTypes();
097: int sigOffset = (methodEdit.isStatic()
098: || methodEdit.isConstructor() ? 0 : 1);
099: if (argTypes.length != (sigTypes.length - sigOffset)) {
100: return false;
101: }
102: for (int idx = 0; idx < argTypes.length; idx++) {
103: if (!argTypes[idx].className().equals(
104: sigTypes[idx + sigOffset].className())) {
105: return false;
106: }
107: }
108: return true;
109: }
110:
111: public ClassEditor classEditor(String className)
112: throws ClassNotFoundException {
113: return new ClassEditor(context, loader.loadClass(className));
114: }
115:
116: public ClassEditor classEditor(int modifiers, String className,
117: Type super Class, Type[] interfaces) {
118: return new ClassEditor(context, modifiers, className,
119: super Class, interfaces);
120: }
121:
122: public Type super Type(Type type) throws ClassNotFoundException {
123: ClassInfo classInfo = loader.loadClass(type.className());
124: return new ClassEditor(new CachingBloatContext(loader,
125: new ArrayList(), false), classInfo).super class();
126: }
127:
128: public void commit() {
129: try {
130: context.commit();
131: } catch (ConcurrentModificationException exc) {
132: exc.printStackTrace();
133: throw exc;
134: }
135: }
136: }
|