001: /*******************************************************************************
002: * Copyright (c) 2006, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.launcher;
011:
012: import java.io.File;
013:
014: import org.eclipse.core.runtime.CoreException;
015: import org.eclipse.core.runtime.ISafeRunnable;
016: import org.eclipse.debug.core.DebugException;
017: import org.eclipse.debug.core.model.IValue;
018: import org.eclipse.debug.core.sourcelookup.ISourceContainer;
019: import org.eclipse.jdt.debug.core.IJavaClassType;
020: import org.eclipse.jdt.debug.core.IJavaFieldVariable;
021: import org.eclipse.jdt.debug.core.IJavaObject;
022: import org.eclipse.jdt.debug.core.IJavaReferenceType;
023: import org.eclipse.jdt.debug.core.IJavaStackFrame;
024: import org.eclipse.osgi.service.resolver.BundleDescription;
025: import org.eclipse.osgi.service.resolver.State;
026: import org.eclipse.pde.core.plugin.IPluginModelBase;
027: import org.eclipse.pde.internal.core.PDECore;
028: import org.eclipse.pde.internal.core.TargetPlatformHelper;
029:
030: public class PDESourceLookupQuery implements ISafeRunnable {
031:
032: protected static String OSGI_CLASSLOADER = "org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader"; //$NON-NLS-1$
033: private static String LEGACY_ECLIPSE_CLASSLOADER = "org.eclipse.core.runtime.adaptor.EclipseClassLoader"; //$NON-NLS-1$
034: private static String MAIN_CLASS = "org.eclipse.core.launcher.Main"; //$NON-NLS-1$
035: private static String MAIN_PLUGIN = "org.eclipse.platform"; //$NON-NLS-1$
036:
037: private Object fElement;
038: private Object fResult;
039: private PDESourceLookupDirector fDirector;
040:
041: public PDESourceLookupQuery(PDESourceLookupDirector director,
042: Object object) {
043: fElement = object;
044: fDirector = director;
045: }
046:
047: public void handleException(Throwable exception) {
048: }
049:
050: public void run() throws Exception {
051: IJavaObject classLoaderObject = null;
052: String declaringTypeName = null;
053: String sourcePath = null;
054: if (fElement instanceof IJavaStackFrame) {
055: IJavaStackFrame stackFrame = (IJavaStackFrame) fElement;
056: classLoaderObject = stackFrame.getReferenceType()
057: .getClassLoaderObject();
058: declaringTypeName = stackFrame.getDeclaringTypeName();
059: sourcePath = generateSourceName(declaringTypeName);
060: } else if (fElement instanceof IJavaObject) {
061: IJavaObject object = (IJavaObject) fElement;
062: IJavaReferenceType type = (IJavaReferenceType) object
063: .getJavaType();
064: classLoaderObject = type.getClassLoaderObject();
065: if (object.getJavaType() != null) {
066: declaringTypeName = object.getJavaType().getName();
067: }
068: if (declaringTypeName != null) {
069: sourcePath = generateSourceName(declaringTypeName);
070: }
071: } else if (fElement instanceof IJavaReferenceType) {
072: IJavaReferenceType type = (IJavaReferenceType) fElement;
073: classLoaderObject = type.getClassLoaderObject();
074: declaringTypeName = type.getName();
075: sourcePath = generateSourceName(declaringTypeName);
076: }
077:
078: if (classLoaderObject != null) {
079: IJavaClassType type = (IJavaClassType) classLoaderObject
080: .getJavaType();
081: if (OSGI_CLASSLOADER.equals(type.getName())) {
082: fResult = findSourceElement(classLoaderObject,
083: sourcePath);
084: } else if (LEGACY_ECLIPSE_CLASSLOADER
085: .equals(type.getName())) {
086: fResult = findSourceElement_legacy(classLoaderObject,
087: sourcePath);
088: } else if (MAIN_CLASS.equals(declaringTypeName)) {
089: IPluginModelBase model = PDECore.getDefault()
090: .getModelManager().findModel(MAIN_PLUGIN);
091: if (model != null)
092: fResult = getSourceElement(model
093: .getInstallLocation(), MAIN_PLUGIN,
094: sourcePath);
095: }
096: }
097: }
098:
099: protected Object getResult() {
100: return fResult;
101: }
102:
103: private String getValue(IJavaObject object, String variable)
104: throws DebugException {
105: IJavaFieldVariable var = object.getField(variable, false);
106: return var == null ? null : var.getValue().getValueString();
107: }
108:
109: protected Object findSourceElement(IJavaObject object,
110: String typeName) throws CoreException {
111: IJavaObject manager = getObject(object, "manager", false); //$NON-NLS-1$
112: if (manager != null) {
113: IJavaObject data = getObject(manager, "data", false); //$NON-NLS-1$
114: if (data != null) {
115: String location = getValue(data, "fileName"); //$NON-NLS-1$
116: String id = getValue(data, "symbolicName"); //$NON-NLS-1$
117: return getSourceElement(location, id, typeName);
118: }
119: }
120: return null;
121: }
122:
123: private IJavaObject getObject(IJavaObject object, String field,
124: boolean super field) throws DebugException {
125: IJavaFieldVariable variable = object
126: .getField(field, super field);
127: if (variable != null) {
128: IValue value = variable.getValue();
129: if (value instanceof IJavaObject)
130: return (IJavaObject) value;
131: }
132: return null;
133: }
134:
135: private Object findSourceElement_legacy(IJavaObject object,
136: String typeName) throws CoreException {
137: IJavaObject hostdata = getObject(object, "hostdata", true); //$NON-NLS-1$
138: if (hostdata != null) {
139: String location = getValue(hostdata, "fileName"); //$NON-NLS-1$
140: String id = getValue(hostdata, "symbolicName"); //$NON-NLS-1$
141: return getSourceElement(location, id, typeName);
142: }
143: return null;
144: }
145:
146: private Object getSourceElement(String location, String id,
147: String typeName) throws CoreException {
148: if (location != null && id != null) {
149: Object result = findSourceElement(getSourceContainers(
150: location, id), typeName);
151: if (result != null)
152: return result;
153:
154: // don't give up yet, search fragments attached to this host
155: State state = TargetPlatformHelper.getState();
156: BundleDescription desc = state.getBundle(id, null);
157: if (desc != null) {
158: BundleDescription[] fragments = desc.getFragments();
159: for (int i = 0; i < fragments.length; i++) {
160: location = fragments[i].getLocation();
161: id = fragments[i].getSymbolicName();
162: result = findSourceElement(getSourceContainers(
163: location, id), typeName);
164: if (result != null)
165: return result;
166: }
167: }
168: }
169: return null;
170: }
171:
172: private Object findSourceElement(ISourceContainer[] containers,
173: String typeName) throws CoreException {
174: for (int i = 0; i < containers.length; i++) {
175: Object[] result = containers[i]
176: .findSourceElements(typeName);
177: if (result.length > 0)
178: return result[0];
179: }
180: return null;
181: }
182:
183: protected ISourceContainer[] getSourceContainers(String location,
184: String id) throws CoreException {
185: return fDirector.getSourceContainers(location, id);
186: }
187:
188: /**
189: * Generates and returns a source file path based on a qualified type name.
190: * For example, when <code>java.lang.String</code> is provided,
191: * the returned source name is <code>java/lang/String.java</code>.
192: *
193: * @param qualifiedTypeName fully qualified type name that may contain inner types
194: * denoted with <code>$</code> character
195: * @return a source file path corresponding to the type name
196: */
197: private static String generateSourceName(String qualifiedTypeName) {
198: int index = qualifiedTypeName.indexOf('$');
199: if (index >= 0)
200: qualifiedTypeName = qualifiedTypeName.substring(0, index);
201: return qualifiedTypeName.replace('.', File.separatorChar)
202: + ".java"; //$NON-NLS-1$
203: }
204:
205: }
|