blob: 86d00dd9ff1be31942e313304d9e6006d7e63fd4 [file] [log] [blame]
/*
* Copyright (c) 2011-2013, 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
* Simon McDuff - bug 226778
* Simon McDuff - bug 230832
* Simon McDuff - bug 233490
* Simon McDuff - bug 213402
* Victor Roldan Betancort - maintenance
*/
package org.eclipse.emf.internal.cdo.session;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.cdo.view.CDOViewContainer;
import org.eclipse.emf.cdo.view.CDOViewProvider;
import org.eclipse.emf.internal.cdo.view.CDOViewImpl;
import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.container.Container;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.spi.cdo.InternalCDOView;
import org.eclipse.emf.spi.cdo.InternalCDOViewSet;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author Eike Stepper
*/
public abstract class CDOViewContainerImpl extends Container<CDOView>implements CDOViewContainer
{
public static final ThreadLocal<CDOViewProvider> VIEW_PROVIDER = new ThreadLocal<CDOViewProvider>();
private Set<InternalCDOView> views = new HashSet<InternalCDOView>();
@ExcludeFromDump
private int lastViewID;
public CDOViewContainerImpl()
{
}
public CDOView getView(int viewID)
{
checkActive();
for (InternalCDOView view : getViews())
{
if (view.getViewID() == viewID)
{
return view;
}
}
return null;
}
/**
* @since 2.0
*/
public InternalCDOView[] getViews()
{
return getViews(null);
}
public InternalCDOView[] getViews(CDOBranch branch)
{
List<InternalCDOView> views = getViews(branch, false);
return views.toArray(new InternalCDOView[views.size()]);
}
protected List<InternalCDOView> getViews(CDOBranch branch, boolean writeable)
{
checkActive();
synchronized (views)
{
List<InternalCDOView> result = new ArrayList<InternalCDOView>();
for (InternalCDOView view : views)
{
if (branch != null && branch != view.getBranch())
{
continue;
}
if (writeable && view.isReadOnly())
{
continue;
}
result.add(view);
}
return result;
}
}
public CDOView[] getElements()
{
return getViews();
}
@Override
public boolean isEmpty()
{
checkActive();
return views.isEmpty();
}
public CDOView openView(CDOBranchPoint target, ResourceSet resourceSet)
{
return openView(target.getBranch(), target.getTimeStamp(), resourceSet);
}
public CDOView openView(CDOBranchPoint target)
{
return openView(target, createResourceSet());
}
public InternalCDOView openView(CDOBranch branch, long timeStamp, ResourceSet resourceSet)
{
checkActive();
InternalCDOView view = createView(branch, timeStamp);
initView(view, resourceSet);
return view;
}
public InternalCDOView openView(CDOBranch branch, long timeStamp)
{
return openView(branch, timeStamp, createResourceSet());
}
public InternalCDOView openView(CDOBranch branch)
{
return openView(branch, CDOBranchPoint.UNSPECIFIED_DATE);
}
public InternalCDOView openView(long timeStamp)
{
return openView(getMainBranch(), timeStamp);
}
public InternalCDOView openView(ResourceSet resourceSet)
{
return openView(getMainBranch(), CDOBranchPoint.UNSPECIFIED_DATE, resourceSet);
}
/**
* @since 2.0
*/
public InternalCDOView openView()
{
return openView(CDOBranchPoint.UNSPECIFIED_DATE);
}
public CDOView openView(String durableLockingID)
{
return openView(durableLockingID, createResourceSet());
}
public CDOView openView(String durableLockingID, ResourceSet resourceSet)
{
checkActive();
InternalCDOView view = createView(durableLockingID);
initView(view, resourceSet);
return view;
}
/**
* @since 2.0
*/
public void viewDetached(InternalCDOView view)
{
synchronized (views)
{
if (!views.remove(view))
{
return;
}
}
if (isActive())
{
try
{
LifecycleUtil.deactivate(view);
}
catch (Exception ex)
{
throw WrappedException.wrap(ex);
}
}
fireElementRemovedEvent(view);
}
/**
* @since 2.0
*/
protected InternalCDOView createView(CDOBranch branch, long timeStamp)
{
return new CDOViewImpl(branch, timeStamp);
}
/**
* @since 4.0
*/
protected InternalCDOView createView(String durableLockingID)
{
return new CDOViewImpl(durableLockingID);
}
protected ResourceSet createResourceSet()
{
return new ResourceSetImpl();
}
@Override
protected void doDeactivate() throws Exception
{
for (InternalCDOView view : views.toArray(new InternalCDOView[views.size()]))
{
try
{
view.close();
}
catch (RuntimeException ignore)
{
}
}
views.clear();
super.doDeactivate();
}
/**
* @since 2.0
*/
protected void initView(InternalCDOView view, ResourceSet resourceSet)
{
CDOViewProvider viewProvider = VIEW_PROVIDER.get();
if (viewProvider != null)
{
view.setProvider(viewProvider);
}
InternalCDOViewSet viewSet = SessionUtil.prepareResourceSet(resourceSet);
synchronized (views)
{
view.setViewID(++lastViewID);
initViewSynced(view);
views.add(view); // From now the view.invalidate() method can be called!
}
// Link ViewSet with View
view.setViewSet(viewSet);
viewSet.add(view);
try
{
view.activate();
fireElementAddedEvent(view);
}
catch (RuntimeException ex)
{
synchronized (views)
{
views.remove(view);
}
viewSet.remove(view);
view.deactivate();
throw ex;
}
}
protected void initViewSynced(InternalCDOView view)
{
}
protected abstract CDOBranch getMainBranch();
}