Skip to main content
summaryrefslogblamecommitdiffstats
blob: 670cd9c6aa001dbb3e9ba1b2a1282ced24715bb3 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
  
                                                                







                                                                        
                            
 

                                                     
                                        
                                        







                                                      
                                               
                                            
                                       
                                                 











                                                 
                                                                 
 
                                                                 




                                                                
                                     
   
                                                   








                             
                                            













                                    

                               












































                                                   

                                                    




                        
                                                               

                                                                                                           



                  

































                                                          



                                           
                                                                      








































                                                                     
 










                                                              







                                            
 
/*
 * 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);
  }
}

Back to the top