blob: 2ae0b6d0c0b6561f7fbd44e75cbd26c614aca6c6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2012 Oracle. 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:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.common.core.internal.resource.java.binary;
import java.util.Collection;
import java.util.Vector;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jpt.common.core.JptCommonCorePlugin;
import org.eclipse.jpt.common.core.resource.java.JavaResourceAnnotatedElement;
import org.eclipse.jpt.common.core.resource.java.JavaResourceField;
import org.eclipse.jpt.common.core.resource.java.JavaResourceMethod;
import org.eclipse.jpt.common.core.resource.java.JavaResourceNode;
import org.eclipse.jpt.common.core.resource.java.JavaResourceType;
import org.eclipse.jpt.common.utility.MethodSignature;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable;
import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneIterable;
/**
* binary type
*/
final class BinaryType
extends BinaryAbstractType
implements JavaResourceType
{
private String superclassQualifiedName;
private boolean abstract_; // 'abstract' is a reserved word
private boolean hasNoArgConstructor;
private boolean hasPrivateNoArgConstructor;
private final Vector<JavaResourceField> fields;
private final Vector<JavaResourceMethod> methods;
// ********** construction/initialization **********
BinaryType(JavaResourceNode parent, IType type) {
super(parent, type);
this.superclassQualifiedName = this.buildSuperclassQualifiedName(type);
this.abstract_ = this.buildAbstract(type);
this.hasNoArgConstructor = this.buildHasNoArgConstructor(type);
this.hasPrivateNoArgConstructor = this.buildHasPrivateNoArgConstructor(type);
this.fields = this.buildFields(type);
this.methods = this.buildMethods(type);
}
public Kind getKind() {
return JavaResourceAnnotatedElement.Kind.TYPE;
}
// ********** overrides **********
@Override
protected void update(IMember member) {
super.update(member);
this.setSuperclassQualifiedName(this.buildSuperclassQualifiedName((IType) member));
this.setAbstract(this.buildAbstract((IType) member));
this.setHasNoArgConstructor(this.buildHasNoArgConstructor((IType) member));
this.setHasPrivateNoArgConstructor(this.buildHasPrivateNoArgConstructor((IType) member));
this.updateFields((IType) member);
this.updateMethods((IType) member);
}
// TODO
private void updateFields(IType type) {
throw new UnsupportedOperationException();
}
// TODO
private void updateMethods(IType type) {
throw new UnsupportedOperationException();
}
// ********** JavaResourceType implementation **********
// ***** superclass qualified name
public String getSuperclassQualifiedName() {
return this.superclassQualifiedName;
}
private void setSuperclassQualifiedName(String superclassQualifiedName) {
String old = this.superclassQualifiedName;
this.superclassQualifiedName = superclassQualifiedName;
this.firePropertyChanged(SUPERCLASS_QUALIFIED_NAME_PROPERTY, old, superclassQualifiedName);
}
private String buildSuperclassQualifiedName(IType type) {
return convertTypeSignatureToTypeName(this.getSuperclassTypeSignature(type));
}
private String getSuperclassTypeSignature(IType type) {
try {
return type.getSuperclassTypeSignature();
} catch (JavaModelException ex) {
JptCommonCorePlugin.log(ex);
return null;
}
}
// ***** abstract
public boolean isAbstract() {
return this.abstract_;
}
private void setAbstract(boolean abstract_) {
boolean old = this.abstract_;
this.abstract_ = abstract_;
this.firePropertyChanged(ABSTRACT_PROPERTY, old, abstract_);
}
private boolean buildAbstract(IType type) {
try {
return Flags.isAbstract(type.getFlags());
} catch (JavaModelException ex) {
JptCommonCorePlugin.log(ex);
return false;
}
}
// ***** no-arg constructor
public boolean hasNoArgConstructor() {
return this.hasNoArgConstructor;
}
private void setHasNoArgConstructor(boolean hasNoArgConstructor) {
boolean old = this.hasNoArgConstructor;
this.hasNoArgConstructor = hasNoArgConstructor;
this.firePropertyChanged(NO_ARG_CONSTRUCTOR_PROPERTY, old, hasNoArgConstructor);
}
private boolean buildHasNoArgConstructor(IType type) {
return this.findNoArgConstructor(type) != null;
}
private IMethod findNoArgConstructor(IType type) {
try {
for (IMethod method : type.getMethods()) {
if (method.isConstructor()) {
return method;
}
}
}
catch (JavaModelException ex) {
JptCommonCorePlugin.log(ex);
}
return null;
}
// ***** private no-arg constructor
public boolean hasPrivateNoArgConstructor() {
return this.hasPrivateNoArgConstructor;
}
private void setHasPrivateNoArgConstructor(boolean hasPrivateNoArgConstructor) {
boolean old = this.hasPrivateNoArgConstructor;
this.hasPrivateNoArgConstructor = hasPrivateNoArgConstructor;
this.firePropertyChanged(PRIVATE_NO_ARG_CONSTRUCTOR_PROPERTY, old, hasPrivateNoArgConstructor);
}
private boolean buildHasPrivateNoArgConstructor(IType type) {
IMethod method = this.findNoArgConstructor(type);
try {
return method != null && Flags.isPrivate(method.getFlags());
}
catch (JavaModelException ex) {
JptCommonCorePlugin.log(ex);
return false;
}
}
// ***** public/protected no-arg constructor *****
public boolean hasPublicOrProtectedNoArgConstructor() {
Iterable<JavaResourceMethod> constructors = this.getConstructors();
if (CollectionTools.size(constructors) == 0) {
return true;
}
for (JavaResourceMethod constructor : constructors) {
if (constructor.getParametersSize() == 0) {
return Modifier.isPublic(constructor.getModifiers())
|| Modifier.isProtected(constructor.getModifiers());
}
}
return false;
}
public boolean hasPublicNoArgConstructor() {
Iterable<JavaResourceMethod> constructors = this.getConstructors();
if (CollectionTools.size(constructors) == 0) {
return true;
}
for (JavaResourceMethod constructor : constructors) {
if (constructor.getParametersSize() == 0) {
return Modifier.isPublic(constructor.getModifiers());
}
}
return false;
}
protected Iterable<JavaResourceMethod> getConstructors() {
return new FilteringIterable<JavaResourceMethod>(this.getMethods()) {
@Override
protected boolean accept(JavaResourceMethod method) {
return method.isConstructor();
}
};
}
// ********** misc **********
public boolean hasAnyAnnotatedFields() {
for (JavaResourceField field : this.getFields()) {
if (field.isAnnotated()) {
return true;
}
}
return false;
}
public boolean hasAnyAnnotatedMethods() {
for (JavaResourceMethod method : this.getMethods()) {
if (method.isAnnotated()) {
return true;
}
}
return false;
}
@Override
public IType getMember() {
return super.getMember();
}
// Two more requirements for a valid equals() method:
// 1. It should be public
// 2. The return type should be boolean
// Both requirements are validated by the compiler so they are excluded here
public boolean hasEqualsMethod() {
for (JavaResourceMethod method : this.getMethods()) {
if (StringTools.stringsAreEqual(method.getMethodName(), "equals") //$NON-NLS-1$
&& method.getParametersSize() == 1
&& StringTools.stringsAreEqual(method.getParameterTypeName(0), Object.class.getName())) {
return true;
}
}
return false;
}
// Two more requirements for a valid hashCode() method:
// 1. It should be public
// 2. The return type should be int
// Both requirements are validated by the compiler so they are excluded here
public boolean hasHashCodeMethod() {
for (JavaResourceMethod method : this.getMethods()) {
if (StringTools.stringsAreEqual(method.getMethodName(), "hashCode") //$NON-NLS-1$
&& method.getParametersSize() == 0) {
return true;
}
}
return false;
}
public JavaResourceMethod getMethod(String propertyName) {
for (JavaResourceMethod method : this.getMethods()) {
if (StringTools.stringsAreEqual(method.getMethodName(), propertyName)) {
return method;
}
}
return null;
}
// ********** fields **********
public Iterable<JavaResourceField> getFields() {
return new LiveCloneIterable<JavaResourceField>(this.fields);
}
private void addField(JavaResourceField field) {
this.addItemToCollection(field, this.fields, FIELDS_COLLECTION);
}
private JavaResourceField getField(String fieldName, int occurrence) {
for (JavaResourceField field : this.getFields()) {
if (field.isFor(fieldName, occurrence)) {
return field;
}
}
return null;
}
private void removeFields(Collection<JavaResourceField> remove) {
this.removeItemsFromCollection(remove, this.fields, FIELDS_COLLECTION);
}
private Vector<JavaResourceField> buildFields(IType type) {
IField[] jdtFields = this.getFields(type);
Vector<JavaResourceField> result = new Vector<JavaResourceField>(jdtFields.length);
for (IField jdtField : jdtFields) {
result.add(this.buildField(jdtField));
}
return result;
}
private IField[] getFields(IType type) {
try {
return type.getFields();
} catch (JavaModelException ex) {
JptCommonCorePlugin.log(ex);
return EMPTY_FIELD_ARRAY;
}
}
private static final IField[] EMPTY_FIELD_ARRAY = new IField[0];
private JavaResourceField buildField(IField jdtField) {
return new BinaryField(this, jdtField);
}
// ********** methods **********
public Iterable<JavaResourceMethod> getMethods() {
return new LiveCloneIterable<JavaResourceMethod>(this.methods);
}
private JavaResourceMethod getMethod(MethodSignature signature, int occurrence) {
for (JavaResourceMethod method : this.getMethods()) {
if (method.isFor(signature, occurrence)) {
return method;
}
}
return null;
}
private void addMethod(JavaResourceMethod method) {
this.addItemToCollection(method, this.methods, METHODS_COLLECTION);
}
private void removeMethods(Collection<JavaResourceMethod> remove) {
this.removeItemsFromCollection(remove, this.methods, METHODS_COLLECTION);
}
private Vector<JavaResourceMethod> buildMethods(IType type) {
IMethod[] jdtMethods = this.getMethods(type);
Vector<JavaResourceMethod> result = new Vector<JavaResourceMethod>(jdtMethods.length);
for (IMethod jdtMethod : jdtMethods) {
result.add(this.buildMethod(jdtMethod));
}
return result;
}
private IMethod[] getMethods(IType type) {
try {
return type.getMethods();
} catch (JavaModelException ex) {
JptCommonCorePlugin.log(ex);
return EMPTY_METHOD_ARRAY;
}
}
private static final IMethod[] EMPTY_METHOD_ARRAY = new IMethod[0];
private JavaResourceMethod buildMethod(IMethod jdtMethod) {
return new BinaryMethod(this, jdtMethod);
}
}