| /* |
| * Copyright (c) 2015 Eike Stepper (Berlin, Germany) 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: |
| * Eike Stepper - initial API and implementation |
| */ |
| package org.eclipse.emf.cdo; |
| |
| import org.eclipse.emf.cdo.eresource.CDOResource; |
| import org.eclipse.emf.cdo.eresource.CDOResourceNode; |
| import org.eclipse.emf.cdo.util.CDOUtil; |
| import org.eclipse.emf.cdo.view.CDOView; |
| |
| import org.eclipse.net4j.util.AdapterUtil; |
| |
| import org.eclipse.emf.common.notify.Adapter; |
| import org.eclipse.emf.common.notify.Notifier; |
| import org.eclipse.emf.common.notify.impl.AdapterImpl; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.emf.spi.cdo.FSMUtil; |
| import org.eclipse.emf.spi.cdo.InternalCDOObject; |
| |
| import org.eclipse.core.runtime.IAdaptable; |
| |
| import java.util.ArrayList; |
| import java.util.ConcurrentModificationException; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| /** |
| * @author Eike Stepper |
| * @since 4.4 |
| */ |
| public class CDOElement extends AdapterImpl implements IAdaptable |
| { |
| private static final Class<CDOElement> TYPE = CDOElement.class; |
| |
| private final EObject delegate; |
| |
| private final List<Object> children = new ArrayList<Object>(); |
| |
| public CDOElement(EObject delegate) |
| { |
| this.delegate = (EObject)getInstance(delegate); |
| } |
| |
| public Object getDelegate() |
| { |
| return delegate; |
| } |
| |
| public Object getParent() |
| { |
| return CDOElement.getParentOf(delegate); |
| } |
| |
| public Object[] getChildren() |
| { |
| return children.toArray(); |
| } |
| |
| public boolean hasChildren() |
| { |
| return !children.isEmpty(); |
| } |
| |
| public void addChild(Object child) |
| { |
| child = getInstance(child); |
| |
| EList<Adapter> adapters = removeFrom(child); |
| if (adapters != null) |
| { |
| synchronized (TYPE) |
| { |
| adapters.add(this); |
| } |
| } |
| |
| children.add(child); |
| } |
| |
| public void reset() |
| { |
| children.clear(); |
| } |
| |
| @Override |
| public boolean isAdapterForType(Object type) |
| { |
| return type == TYPE; |
| } |
| |
| @SuppressWarnings({ "rawtypes", "unchecked" }) |
| public Object getAdapter(Class adapter) |
| { |
| if (adapter == EObject.class) |
| { |
| return delegate; |
| } |
| |
| return AdapterUtil.adapt(this, adapter, false); |
| } |
| |
| public String toString(Object child) |
| { |
| return child.toString(); |
| } |
| |
| @Override |
| public String toString() |
| { |
| return delegate.toString(); |
| } |
| |
| public static EObject getParentOf(EObject eObject) |
| { |
| if (eObject == null) |
| { |
| return null; |
| } |
| |
| CDOObject cdoObject = CDOUtil.getCDOObject(eObject, false); |
| if (cdoObject != null |
| && (FSMUtil.isInvalid(cdoObject) || cdoObject.cdoView() == null || cdoObject.cdoView().isClosed())) |
| { |
| return null; |
| } |
| |
| EObject container = eObject.eContainer(); |
| if (container != null) |
| { |
| return container; |
| } |
| |
| if (eObject instanceof CDOResource) |
| { |
| CDOResource resource = (CDOResource)eObject; |
| if (resource.isRoot()) |
| { |
| return null; |
| } |
| } |
| |
| Resource resource = eObject.eResource(); |
| if (resource instanceof CDOResource) |
| { |
| return (CDOResource)resource; |
| } |
| |
| if (eObject instanceof CDOResourceNode) |
| { |
| CDOView view = ((CDOResourceNode)eObject).cdoView(); |
| if (view != null) |
| { |
| return view.getRootResource(); |
| } |
| } |
| |
| return null; |
| } |
| |
| public static CDOElement getFor(Object object) |
| { |
| if (object instanceof Notifier) |
| { |
| Notifier notifier = (Notifier)object; |
| return (CDOElement)EcoreUtil.getExistingAdapter(notifier, TYPE); |
| } |
| |
| return null; |
| } |
| |
| public static EList<Adapter> removeFrom(Object object) |
| { |
| if (object instanceof EObject) |
| { |
| EObject eObject = (EObject)object; |
| EList<Adapter> adapters = eObject.eAdapters(); |
| |
| synchronized (TYPE) |
| { |
| removeSafe(adapters); |
| } |
| |
| return adapters; |
| } |
| |
| return null; |
| } |
| |
| private static void removeSafe(EList<Adapter> adapters) |
| { |
| try |
| { |
| for (Iterator<Adapter> it = adapters.iterator(); it.hasNext();) |
| { |
| Adapter adapter = it.next(); |
| if (adapter.isAdapterForType(TYPE)) |
| { |
| it.remove(); |
| } |
| } |
| } |
| catch (ConcurrentModificationException ex) |
| { |
| removeSafe(adapters); |
| } |
| } |
| |
| private static Object getInstance(Object object) |
| { |
| if (object instanceof InternalCDOObject) |
| { |
| InternalCDOObject cdoObject = (InternalCDOObject)object; |
| object = cdoObject.cdoInternalInstance(); |
| } |
| |
| return object; |
| } |
| |
| /** |
| * @author Eike Stepper |
| * @since 4.4 |
| */ |
| public interface StateProvider |
| { |
| public CDOState getState(Object object); |
| } |
| } |