/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.ode.data.core.repo; import java.awt.datatransfer.DataFlavor; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.activation.CommandObject; import javax.activation.MimeTypeParseException; import javax.inject.Inject; import javax.inject.Provider; import javax.inject.Singleton; import org.apache.ode.spi.repo.Artifact; import org.apache.ode.spi.repo.ArtifactDataSource; import org.apache.ode.spi.repo.Criteria; import org.apache.ode.spi.repo.DataContentHandler; import org.apache.ode.spi.repo.DataHandler; import org.apache.ode.spi.repo.Repository; import org.apache.ode.spi.repo.RepositoryException; @Singleton public abstract class RepositoryBaseImpl implements Repository { @Inject protected RepoFileTypeMap fileTypes; @Inject protected RepoCommandMap commandMap; @Inject protected Provider<ArtifactDataSourceImpl> dsProvider; @Override public <C> UUID create(URI uri, String version, String contentType, C content) throws RepositoryException { Artifact artifact = null; if (content instanceof Artifact) { artifact = (Artifact) content; if (exists(new Criteria(artifact.getURI(), artifact.getContentType(), artifact.getVersion()))) { throw new RepositoryException("ArtifactDataSource already attached to an existing artifact"); } artifact.setURI(uri); artifact.setVersion(version); } else if (content instanceof ArtifactDataSourceImpl) { artifact = ((ArtifactDataSourceImpl) content).getArtifact(); if (exists(new Criteria(uri, contentType, version))) { throw new RepositoryException("ArtifactDataSource already attached to an existing artifact"); } artifact.setURI(uri); artifact.setVersion(version); } else { artifact = new Artifact().withUUID(UUID.randomUUID()).withURI(uri).withVersion(version).withContentType(contentType); if (content instanceof byte[]) { artifact.setContent((byte[]) content); } else { DataHandler dh = getDataHandler(content, contentType); try { artifact.setContent(dh.toContent()); } catch (IOException e) { throw new RepositoryException(e); } } } if (!artifact.getURI().isAbsolute()) { throw new RepositoryException(String.format("Artifact URI must be absolute %s", artifact.getURI())); } createArtifact(artifact); return artifact.getId(); } protected abstract <R> List<Artifact> loadArtifacts(R criteria, long limit) throws RepositoryException; protected abstract void createArtifact(Artifact artifact) throws RepositoryException; protected abstract void storeArtifact(Artifact artifact) throws RepositoryException; protected <R> Artifact getSingle(R criteria) throws RepositoryException { List<Artifact> artifacts = loadArtifacts(criteria, 2); if (artifacts.size() == 0) { throw new RepositoryException(String.format("Artifact %s does not exists", criteria)); } if (artifacts.size() > 1) { throw new RepositoryException(String.format("More than one Artifact exists for criteria %s", criteria)); } return artifacts.get(0); } @Override public <R> boolean exists(R criteria) throws RepositoryException { List<Artifact> artifacts = loadArtifacts(criteria, 2); if (artifacts.size() > 1) { throw new RepositoryException(String.format("More than one Artifact exists for criteria %s", criteria)); } if (artifacts.size() == 1) { return true; } return false; } @Override public <R, C> C read(R criteria, Class<C> javaType) throws RepositoryException { Artifact artifact = getSingle(criteria); if (Artifact.class.isAssignableFrom(javaType)) { return (C) artifact; } ArtifactDataSourceImpl ds = dsProvider.get(); try { ds.configure(artifact); } catch (MimeTypeParseException e) { throw new RepositoryException(e); } if (ArtifactDataSource.class.isAssignableFrom(javaType)) { return (C) ds; } if (byte[].class.isAssignableFrom(javaType)) { return (C) ds.getContent(); } DataHandler dh = getDataHandler(ds); DataFlavor[] flavors = dh.getTransferDataFlavors(); C content = null; for (DataFlavor df : flavors) { if (df.getRepresentationClass().equals(javaType)) { try { content = (C) dh.getTransferData(df); break; } catch (Exception e) { throw new RepositoryException(e); } } } if (content == null) { throw new RepositoryException(String.format("Unable to create Java representation class %s", javaType)); } else { return content; } } @Override public <R, C> List<C> search(R criteria, Class<C> javaType, long limit) throws RepositoryException { List<C> results = new ArrayList<C>(); List<Artifact> artifacts = loadArtifacts(criteria, limit); for (Artifact artifact : artifacts) { if (Artifact.class.isAssignableFrom(javaType)) { results.add((C) artifact); } ArtifactDataSourceImpl ds = dsProvider.get(); try { ds.configure(artifact); } catch (MimeTypeParseException e) { throw new RepositoryException(e); } if (ArtifactDataSource.class.isAssignableFrom(javaType)) { results.add((C) ds); } if (byte[].class.isAssignableFrom(javaType)) { results.add((C) ds.getContent()); } DataHandler dh = getDataHandler(ds); DataFlavor[] flavors = dh.getTransferDataFlavors(); C content = null; for (DataFlavor df : flavors) { if (df.getRepresentationClass().equals(javaType)) { try { content = (C) dh.getTransferData(df); break; } catch (Exception e) { throw new RepositoryException(e); } } } if (content == null) { throw new RepositoryException(String.format("Unable to create Java representation class %s", javaType)); } else { results.add(content); } } return results; } @Override public <R, C> void update(R criteria, C content) throws RepositoryException { Artifact artifact = getSingle(criteria); if (content instanceof Artifact) { artifact.setContent(((Artifact) content).getContent()); } else if (content instanceof ArtifactDataSourceImpl) { ArtifactDataSourceImpl ds = (ArtifactDataSourceImpl) content; artifact.setContent(ds.getContent()); } else if (content instanceof byte[]) { artifact.setContent((byte[]) content); } else { DataHandler dh = getDataHandler(content, artifact.getContentType()); try { artifact.setContent(dh.toContent()); } catch (IOException e) { throw new RepositoryException(e); } } storeArtifact(artifact); } @Override public <T extends CommandObject> void registerCommandInfo(String mimeType, String commandName, boolean preferred, Provider<T> provider) { commandMap.registerCommandInfo(mimeType, new CommandInfo<T>(commandName, null, true, provider)); } @Override public void registerFileExtension(String fileExtension, String mimeType) { fileTypes.registerFileExtension(fileExtension, mimeType); } @Override public void registerNamespace(String namespace, String mimeType) { fileTypes.registerNamespace(namespace, mimeType); } @Override public void registerHandler(String mimeType, DataContentHandler handler) { commandMap.registerDataContentHandler(mimeType, handler); } @Override public DataHandler getDataHandler(ArtifactDataSource ds) { DataHandler dh = new DataHandler(ds); dh.setCommandMap(commandMap); return dh; } @Override public <T> DataHandler getDataHandler(T content, String mimeType) { DataHandler dh = new DataHandler(content, mimeType); dh.setCommandMap(commandMap); return dh; } }