/*******************************************************************************
* Copyright (c) 2008, 2011 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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:
* Institute for Software - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters;
import java.util.ArrayList;
import java.util.SortedSet;
import java.util.TreeSet;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.GetterSetterInsertEditProvider.AccessorKind;
public class GetterSetterContext implements ITreeContentProvider {
public ArrayList<IASTSimpleDeclaration> existingFields = new ArrayList<IASTSimpleDeclaration>();
public ArrayList<IASTFunctionDefinition> existingFunctionDefinitions = new ArrayList<IASTFunctionDefinition>();
public ArrayList<IASTSimpleDeclaration> existingFunctionDeclarations = new ArrayList<IASTSimpleDeclaration>();
public SortedSet<GetterSetterInsertEditProvider> selectedFunctions = new TreeSet<GetterSetterInsertEditProvider>();
public IASTName selectedName;
private ArrayList<FieldWrapper> wrappedFields;
private boolean implementationInHeader = false;
public Object[] getChildren(Object parentElement) {
ArrayList<GetterSetterInsertEditProvider> children = new ArrayList<GetterSetterInsertEditProvider>();
if (parentElement instanceof FieldWrapper) {
FieldWrapper wrapper = (FieldWrapper) parentElement;
if (wrapper.getChildNodes().isEmpty()) {
if (!wrapper.getter.exists()) {
wrapper.childNodes.add(createGetterInserter(wrapper.field));
}
if (!wrapper.setter.exists() && !wrapper.field.getDeclSpecifier().isConst()) {
wrapper.childNodes.add(createSetterInserter(wrapper.field));
}
}
children = wrapper.getChildNodes();
}
return children.toArray();
}
public GetterSetterInsertEditProvider createGetterInserter(IASTSimpleDeclaration simpleDeclaration) {
IASTName fieldName = getFieldDeclarationName(simpleDeclaration);
return new GetterSetterInsertEditProvider(fieldName, simpleDeclaration, AccessorKind.GETTER);
}
public GetterSetterInsertEditProvider createSetterInserter(IASTSimpleDeclaration simpleDeclaration) {
IASTName fieldName = getFieldDeclarationName(simpleDeclaration);
return new GetterSetterInsertEditProvider(fieldName, simpleDeclaration, AccessorKind.SETTER);
}
public Object getParent(Object element) {
return null;
}
public boolean hasChildren(Object element) {
if (element instanceof FieldWrapper) {
FieldWrapper wrapper = (FieldWrapper) element;
return wrapper.missingGetterOrSetter();
}
return false;
}
public Object[] getElements(Object inputElement) {
return getWrappedFields().toArray();
}
public void refresh() {
// We only recreate the function declarations instead of recreating GetterSetterInsertEditProviders.
// That way, selectedFunctions is still valid. Also, the objects inside the TreeViewer are still the same
// which is convenient because that way we don't need to save then restore the collapsed/expanded+checked/unchecked state of the TreeViewer.
for (FieldWrapper wrapper : wrappedFields) {
for (GetterSetterInsertEditProvider provider : wrapper.childNodes) {
provider.createFunctionDeclaration();
}
}
}
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
public boolean isImplementationInHeader() {
return implementationInHeader;
}
public void setImplementationInHeader(boolean implementationInHeader) {
this.implementationInHeader = implementationInHeader;
}
private ArrayList<FieldWrapper> getWrappedFields() {
if (wrappedFields == null) {
wrappedFields = new ArrayList<FieldWrapper>();
for (IASTSimpleDeclaration currentField : existingFields) {
FieldWrapper wrapper = new FieldWrapper();
wrapper.field = currentField;
wrapper.getter = getGetterForField(currentField);
wrapper.setter = getSetterForField(currentField);
if (wrapper.missingGetterOrSetter()) {
wrappedFields.add(wrapper);
}
}
}
return wrappedFields;
}
private FunctionWrapper getGetterForField(IASTSimpleDeclaration currentField) {
FunctionWrapper wrapper = new FunctionWrapper();
String name = GetterSetterNameGenerator.generateGetterName(getFieldDeclarationName(currentField));
setFunctionToWrapper(wrapper, name);
return wrapper;
}
private IASTName getFieldDeclarationName(IASTSimpleDeclaration fieldDeclaration) {
IASTDeclarator declarator = fieldDeclaration.getDeclarators()[0];
while (declarator.getNestedDeclarator() != null) {
declarator = declarator.getNestedDeclarator();
}
return declarator.getName();
}
private FunctionWrapper getSetterForField(IASTSimpleDeclaration currentField) {
FunctionWrapper wrapper = new FunctionWrapper();
String name = GetterSetterNameGenerator.generateSetterName(getFieldDeclarationName(currentField));
setFunctionToWrapper(wrapper, name);
return wrapper;
}
private void setFunctionToWrapper(FunctionWrapper wrapper, String getterName) {
for (IASTFunctionDefinition currentDefinition : existingFunctionDefinitions) {
if (currentDefinition.getDeclarator().getName().toString().endsWith(getterName)) {
wrapper.functionDefinition = currentDefinition;
}
}
for (IASTSimpleDeclaration currentDeclaration : existingFunctionDeclarations) {
if (getFieldDeclarationName(currentDeclaration).toString().endsWith(getterName)) {
wrapper.functionDeclaration = currentDeclaration;
}
}
}
protected class FieldWrapper {
protected IASTSimpleDeclaration field;
protected FunctionWrapper getter;
protected FunctionWrapper setter;
protected ArrayList<GetterSetterInsertEditProvider> childNodes = new ArrayList<GetterSetterInsertEditProvider>(2);
@Override
public String toString() {
IASTDeclarator declarator = field.getDeclarators()[0];
while (declarator.getNestedDeclarator() != null) {
declarator = declarator.getNestedDeclarator();
}
return declarator.getName().toString();
}
public ArrayList<GetterSetterInsertEditProvider> getChildNodes() {
return childNodes;
}
public boolean missingGetterOrSetter() {
return !getter.exists() || !setter.exists();
}
}
protected class FunctionWrapper {
protected IASTSimpleDeclaration functionDeclaration;
protected IASTFunctionDefinition functionDefinition;
public boolean exists() {
return functionDeclaration != null || functionDefinition != null;
}
}
}