/* * Copyright (c) 2012 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.transfer.spi.repository; import org.eclipse.emf.cdo.common.branch.CDOBranch; import org.eclipse.emf.cdo.common.lob.CDOBlob; import org.eclipse.emf.cdo.common.lob.CDOClob; import org.eclipse.emf.cdo.common.util.CDOException; import org.eclipse.emf.cdo.eresource.CDOBinaryResource; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.eresource.CDOResourceFolder; import org.eclipse.emf.cdo.eresource.CDOResourceNode; import org.eclipse.emf.cdo.eresource.CDOTextResource; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.transfer.CDOTransferElement; import org.eclipse.emf.cdo.transfer.CDOTransferSystem; import org.eclipse.emf.cdo.transfer.CDOTransferType; import org.eclipse.emf.cdo.util.CDOURIUtil; import org.eclipse.emf.cdo.util.CommitException; import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.net4j.util.io.IORuntimeException; import org.eclipse.net4j.util.io.IOUtil; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import java.io.ByteArrayInputStream; import java.io.CharArrayWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; /** * A CDO {@link #getView() repository}-based implementation of a {@link CDOTransferSystem transfer system}. * * @author Eike Stepper * @since 4.2 */ public class RepositoryTransferSystem extends CDOTransferSystem { public static final String TYPE = "repository"; private final CDOView view; public RepositoryTransferSystem(CDOView view) { super(view.isReadOnly()); this.view = view; } @Override public String getType() { return TYPE; } public CDOView getView() { return view; } public RepositoryTransferSystem makeWriteable() { if (isReadOnly()) { CDOBranch branch = view.getBranch(); CDOSession session = view.getSession(); CDOTransaction transaction = session.openTransaction(branch); return new RepositoryTransferSystem(transaction); } return this; } @Override public CDOTransferType getDefaultTransferType(CDOTransferElement element) { if (element instanceof Element) { CDOResourceNode node = ((Element)element).node; if (node instanceof CDOResource) { return CDOTransferType.MODEL; } if (node instanceof CDOTextResource) { String encoding = ((CDOTextResource)node).getEncoding(); return CDOTransferType.text(encoding); } if (node instanceof CDOBinaryResource) { return CDOTransferType.BINARY; } } return super.getDefaultTransferType(element); } @Override protected ResourceSet provideResourceSet() { return view.getResourceSet(); } @Override public URI getURI(IPath path) { return CDOURIUtil.createResourceURI(view, path.toString()); } @Override public CDOTransferElement getElement(IPath path) { if (path.isEmpty()) { return new RootElement(this, view.getRootResource()); } try { CDOResourceNode node = view.getResourceNode(path.toString()); if (node != null) { return new Element(this, node); } } catch (Exception ex) { //$FALL-THROUGH$ } return null; } @Override public CDOTransferElement getElement(URI uri) { if (CDOURIUtil.PROTOCOL_NAME.equals(uri.scheme())) { return getElement(uri.path()); } return null; } @Override public void createFolder(IPath path) { ((CDOTransaction)view).createResourceFolder(path.toString()); } @Override public void createBinary(IPath path, InputStream source, IProgressMonitor monitor) { try { monitor.beginTask("", 1); CDOBlob blob = new CDOBlob(source); CDOBinaryResource resource = ((CDOTransaction)view).createBinaryResource(path.toString()); resource.setContents(blob); monitor.worked(1); // TODO Progress more smoothly } catch (IOException ex) { throw new IORuntimeException(ex); } finally { monitor.done(); } } @Override public void createText(IPath path, InputStream source, String encoding, IProgressMonitor monitor) { try { monitor.beginTask("", 1); CDOClob clob = new CDOClob(new InputStreamReader(source, encoding)); CDOTextResource resource = ((CDOTransaction)view).createTextResource(path.toString()); resource.setContents(clob); resource.setEncoding(encoding); monitor.worked(1); // TODO Progress more smoothly } catch (IOException ex) { throw new IORuntimeException(ex); } finally { monitor.done(); } } @Override public void saveModels(EList<Resource> resources, IProgressMonitor monitor) { try { monitor.subTask("Committing to " + this); CDOTransaction transaction = (CDOTransaction)view; transaction.commit(monitor); } catch (CommitException ex) { throw new CDOException(ex); } } @Override public String toString() { return "Repository " + view.getSession().getRepositoryInfo().getName(); } /** * @author Eike Stepper */ private static class RootElement extends CDOTransferElement { private CDOResource rootResource; public RootElement(CDOTransferSystem system, CDOResource rootResource) { super(system); this.rootResource = rootResource; } @Override public Object getNativeObject() { return rootResource; } @Override public IPath getPath() { return Path.EMPTY; } @Override public boolean isDirectory() { return true; } @Override protected CDOTransferElement[] doGetChildren() { EList<EObject> children = rootResource.getContents(); int size = children.size(); CDOTransferElement[] result = new Element[size]; for (int i = 0; i < size; i++) { CDOResourceNode child = (CDOResourceNode)children.get(i); result[i] = new Element(getSystem(), child); } return result; } @Override protected InputStream doOpenInputStream() { throw new UnsupportedOperationException(); } } /** * @author Eike Stepper */ private static class Element extends CDOTransferElement { private CDOResourceNode node; public Element(CDOTransferSystem system, CDOResourceNode node) { super(system); this.node = node; } @Override public Object getNativeObject() { return node; } @Override public IPath getPath() { return new Path(node.getPath()); } @Override public boolean isDirectory() { return node instanceof CDOResourceFolder; } @Override protected CDOTransferElement[] doGetChildren() { EList<CDOResourceNode> children = ((CDOResourceFolder)node).getNodes(); int size = children.size(); CDOTransferElement[] result = new Element[size]; for (int i = 0; i < size; i++) { CDOResourceNode child = children.get(i); result[i] = new Element(getSystem(), child); } return result; } @Override protected InputStream doOpenInputStream() { try { if (node instanceof CDOBinaryResource) { CDOBinaryResource resource = (CDOBinaryResource)node; return resource.getContents().getContents(); } if (node instanceof CDOTextResource) { CDOTextResource resource = (CDOTextResource)node; Reader reader = resource.getContents().getContents(); CharArrayWriter buffer = new CharArrayWriter(); // TODO Make more scalable try { IOUtil.copyCharacter(reader, buffer); } finally { IOUtil.close(reader); } String encoding = resource.getEncoding(); byte[] bytes = buffer.toString().getBytes(encoding); return new ByteArrayInputStream(bytes); } } catch (IOException ex) { throw new IORuntimeException(ex); } throw new IllegalStateException("Not a file resource: " + node); } } }