/******************************************************************************* * Copyright (c) 2001, 2005 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jem.internal.adapters.jdom; /* */ import java.util.Map; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecore.xmi.XMIResource; import org.eclipse.jdt.core.*; import org.eclipse.jem.internal.java.adapters.ReadAdaptor; import org.eclipse.jem.internal.java.adapters.nls.ResourceHandler; import org.eclipse.jem.java.*; import org.eclipse.jem.java.internal.impl.FieldImpl; /** * Insert the type's description here. * Creation date: (6/6/2000 4:42:50 PM) * @author: Administrator */ public class JavaFieldJDOMAdaptor extends JDOMAdaptor { private static final String BEGIN_COMMENT = "/*"; //$NON-NLS-1$ private static final String END_COMMENT = "*/"; //$NON-NLS-1$ protected IField sourceField = null; protected IType parentType = null; public JavaFieldJDOMAdaptor(Notifier target, IJavaProject workingProject) { super(target, workingProject); } protected void clearSource() { sourceField = null; } protected boolean flushReflectedValues(boolean clearCachedModelObject) { if (clearCachedModelObject) clearSource(); FieldImpl field = getTargetField(); field.setInitializer(null); field.setFinal(false); field.setStatic(false); field.setTransient(false); field.setVolatile(false); field.setJavaVisibility(JavaVisibilityKind.PUBLIC_LITERAL); field.setEType(null); return true; } protected void postFlushReflectedValuesIfNecessary(boolean isExisting) { getTargetField().setReflected(false); super.postFlushReflectedValuesIfNecessary(isExisting); } /** * Return a String for the source starting after the field's name to the end of * the source range. This will be the source after the name which could include comments. */ protected String getFieldInitializerSource() { IOpenable openable = getSourceField().getOpenable(); try { ISourceRange nameRange, sourceRange; int start = -1, length = 0; IBuffer buffer = openable.getBuffer(); if (buffer == null) { return ""; //$NON-NLS-1$ } nameRange = getSourceField().getNameRange(); start = nameRange.getOffset() + nameRange.getLength(); if (start != -1) { sourceRange = getSourceField().getSourceRange(); if (sourceRange.getOffset() != -1) length = sourceRange.getOffset() + sourceRange.getLength() - start; return buffer.getText(start, length); } return null; } catch (JavaModelException e) { return ""; //$NON-NLS-1$ } } /** * Return the field source string without comments */ protected String getFieldInitializerSourceWithoutComments() { String s = getFieldInitializerSource(); int start = 0; int startComment = -1; int endComment = -1; while (start < s.length()) { startComment = s.indexOf(BEGIN_COMMENT, start); if (startComment > 0) { String newString; endComment = s.indexOf(END_COMMENT, start); newString = s.substring(start, startComment); s = newString + s.substring(endComment + END_COMMENT.length(), s.length()); start = 0; startComment = -1; endComment = -1; } else { start = s.length(); } } return s; } /** * getFieldInitializerString - parse the source for our source field * and return the initialization string. * Return null if no initialization string or constant value is present. * i.e. - public String foo = "foo default"; should return "foo default" (including quotes) */ protected String getFieldInitializerString() { String result = null; try { if (!getParentType().isBinary()) { String source = getFieldInitializerSourceWithoutComments(); if (source != null && source.length() != 0) { int equalsPos = source.indexOf('=');//$NON-NLS-1$ int endPos = source.indexOf(',');//$NON-NLS-1$ if (endPos == -1) endPos = source.length() - 1; if (equalsPos != -1 && equalsPos < endPos) { // Copy from after "=" to before ";" or "," result = source.substring(equalsPos + 1, endPos); result = result.trim(); } } } else { // Binary type, see if we can use the constant // it's not clear from the API's, but this is probably only // available for statics. Object constantValue = getSourceField().getConstant(); // Need to convert the constant to a String if (constantValue != null) { result = constantValue.toString(); if (constantValue instanceof String) { result = "\"" + result + "\""; //$NON-NLS-2$//$NON-NLS-1$ } } } } catch (JavaModelException e) { // punt } return result; } /** * getParentType - return the IType which corresponds to our parent JavaClass * we're going to do this a lot, so cache it. */ protected IType getParentType() { if (parentType == null) { Field targetField = (Field) getTarget(); JavaClass parentJavaClass = targetField.getJavaClass(); if (parentJavaClass != null) { JavaClassJDOMAdaptor pa = (JavaClassJDOMAdaptor) EcoreUtil.getAdapter(parentJavaClass.eAdapters(), ReadAdaptor.TYPE_KEY); if (pa != null) parentType = pa.getSourceType(); } } return parentType; } public Object getReflectionSource() { return getSourceField(); } /* (non-Javadoc) * @see org.eclipse.jem.internal.java.adapters.JavaReflectionAdaptor#hasReflectionSource() */ public boolean hasCachedReflectionSource() { return sourceField != null; } /* * Used by Java Class JDOM adapter to create and set with a source field */ public void setSourceField(IField field) { sourceField = field; } /** * getSourceField - return the IField which describes our implementing field */ protected IField getSourceField() { if (sourceField == null || !sourceField.exists()) { IType parent = this.getParentType(); if (parent != null) sourceField = parent.getField(((Field) getTarget()).getName()); } return sourceField; } public FieldImpl getTargetField() { return (FieldImpl) getTarget(); } protected IType getType() { return getParentType(); } protected Map getTypeResolutionCache() { Field field = getTargetField(); if (field != null) { JavaClass javaClass = field.getJavaClass(); if (javaClass != null) { JDOMAdaptor classAdaptor = (JDOMAdaptor) retrieveAdaptorFrom(javaClass); if (classAdaptor != null) return classAdaptor.getTypeResolutionCache(); } } return null; } /** * getValueIn method comment. */ public Object getValueIn(EObject object, EObject attribute) { // At this point, this adapter does not dynamically compute any values, // all values are pushed back into the target on the initial call. return super.getValueIn(object, attribute); } /** * reflectValues - template method, subclasses override to pump values into target. * on entry: name, containing package (and qualified name), and document must be set. * JavaClass adaptor: * - set modifiers * - set name * - set type */ public boolean reflectValues() { super.reflectValues(); if (isResourceLoaded() && getSourceProject() != null && getSourceField() != null) { setModifiers(); // setNaming(); setType(); return true; } return false; } /** * setModifiers - set the attribute values related to modifiers here */ protected void setModifiers() { Field javaFieldTarget = (Field) getTarget(); try { String initializer = getFieldInitializerString(); if (initializer != null) javaFieldTarget.setInitializer(createBlock(javaFieldTarget.getName(), initializer)); int flags = getSourceField().getFlags(); javaFieldTarget.setFinal(Flags.isFinal(flags)); javaFieldTarget.setStatic(Flags.isStatic(flags)); javaFieldTarget.setTransient(Flags.isTransient(flags)); javaFieldTarget.setVolatile(Flags.isVolatile(flags)); // Set visibility if (Flags.isPublic(flags)) javaFieldTarget.setJavaVisibility(JavaVisibilityKind.PUBLIC_LITERAL); else if (Flags.isPrivate(flags)) javaFieldTarget.setJavaVisibility(JavaVisibilityKind.PRIVATE_LITERAL); else if (Flags.isProtected(flags)) javaFieldTarget.setJavaVisibility(JavaVisibilityKind.PROTECTED_LITERAL); else javaFieldTarget.setJavaVisibility(JavaVisibilityKind.PACKAGE_LITERAL); } catch (JavaModelException npe) { System.out.println(ResourceHandler.getString("Error_Introspecting_Flags_ERROR_", new Object[] {((XMIResource) javaFieldTarget.eResource()).getID(javaFieldTarget), npe.getMessage()})); //$NON-NLS-1$ = "error introspecting flags on {0}" } } /** * setNaming - set the naming values here * - qualified name must be set first, that is the path to the real Java class * - ID * - null UUID */ protected void setNaming() { Field javaFieldTarget = (Field) getTarget(); JavaClass parent = javaFieldTarget.getContainingJavaClass(); ((XMIResource) javaFieldTarget.eResource()).setID(javaFieldTarget, parent.getName() + "_" + javaFieldTarget.getName()); //$NON-NLS-1$ } /** * setType - set our type here */ protected void setType() { String typeName = null; try { typeName = typeNameFromSignature(getSourceField().getTypeSignature()); } catch (JavaModelException npe) { // name stays null and we carry on } setFieldType(getTargetField(), typeName); } }