http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/3ecb1291/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/HibernateReferenceSetDao.java ---------------------------------------------------------------------- diff --git a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/HibernateReferenceSetDao.java b/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/HibernateReferenceSetDao.java deleted file mode 100644 index 06791a6..0000000 --- a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/HibernateReferenceSetDao.java +++ /dev/null @@ -1,197 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2007 The University of Manchester - * - * Modifications to the initial code base are copyright of their - * respective authors, or their employers as appropriate. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - ******************************************************************************/ -package net.sf.taverna.t2.reference.impl; - -import static net.sf.taverna.t2.reference.T2ReferenceType.ReferenceSet; - -import java.util.List; - -import net.sf.taverna.t2.reference.DaoException; -import net.sf.taverna.t2.reference.ReferenceSet; -import net.sf.taverna.t2.reference.ReferenceSetDao; -import net.sf.taverna.t2.reference.T2Reference; -import net.sf.taverna.t2.reference.annotations.DeleteIdentifiedOperation; -import net.sf.taverna.t2.reference.annotations.GetIdentifiedOperation; -import net.sf.taverna.t2.reference.annotations.PutIdentifiedOperation; - -import org.hibernate.Query; -import org.hibernate.Session; -import org.springframework.orm.hibernate3.support.HibernateDaoSupport; - -/** - * An implementation of ReferenceSetDao based on Spring's HibernateDaoSupport. - * To use this in spring inject a property 'sessionFactory' with either a - * {@link org.springframework.orm.hibernate3.LocalSessionFactoryBean - * LocalSessionFactoryBean} or the equivalent class from the T2Platform module - * to add SPI based implementation discovery and mapping. To use outside of - * Spring ensure you call the setSessionFactory(..) method before using this - * (but really, use it from Spring, so much easier). - * - * @author Tom Oinn - */ -public class HibernateReferenceSetDao extends HibernateDaoSupport implements - ReferenceSetDao { - private static final String GET_REFSETS_FOR_RUN = "FROM ReferenceSetImpl WHERE namespacePart = :workflow_run_id"; - - /** - * Store the specified new reference set - * - * @param rs - * a reference set, must not already exist in the database. - * @throws DaoException - * if the entry already exists in the database, if the supplied - * reference set isn't an instance of ReferenceSetImpl or if - * something else goes wrong connecting to the database - */ - @Override - @PutIdentifiedOperation - public void store(ReferenceSet rs) throws DaoException { - if (rs.getId() == null) - throw new DaoException( - "Supplied reference set has a null ID, allocate " - + "an ID before calling the store method in the dao."); - if (!rs.getId().getReferenceType().equals(ReferenceSet)) - throw new DaoException( - "Strangely the reference set ID doesn't have type " - + "T2ReferenceType.ReferenceSet, something has probably " - + "gone badly wrong somewhere earlier!"); - if (!(rs instanceof ReferenceSetImpl)) - throw new DaoException( - "Supplied reference set not an instance of ReferenceSetImpl"); - - try { - getHibernateTemplate().save(rs); - } catch (Exception ex) { - throw new DaoException(ex); - } - } - - /** - * Update a pre-existing entry in the database - * - * @param rs - * the reference set to update. This must already exist in the - * database - * @throws DaoException - */ - @Override - @PutIdentifiedOperation - public void update(ReferenceSet rs) throws DaoException { - if (rs.getId() == null) - throw new DaoException( - "Supplied reference set has a null ID, allocate " - + "an ID before calling the store method in the dao."); - if (!rs.getId().getReferenceType().equals(ReferenceSet)) - throw new DaoException( - "Strangely the reference set ID doesn't have type " - + "T2ReferenceType.ReferenceSet, something has probably " - + "gone badly wrong somewhere earlier!"); - if (!(rs instanceof ReferenceSetImpl)) - throw new DaoException( - "Supplied reference set not an instance of ReferenceSetImpl"); - - try { - getHibernateTemplate().update(rs); - } catch (Exception ex) { - throw new DaoException(ex); - } - } - - /** - * Fetch a reference set by id - * - * @param ref - * the ReferenceSetT2ReferenceImpl to fetch - * @return a retrieved ReferenceSetImpl - * @throws DaoException - * if the supplied reference is of the wrong type or if - * something goes wrong fetching the data or connecting to the - * database - */ - @Override - @GetIdentifiedOperation - public ReferenceSetImpl get(T2Reference ref) throws DaoException { - if (ref == null) - throw new DaoException( - "Supplied reference is null, can't retrieve."); - if (!ref.getReferenceType().equals(ReferenceSet)) - throw new DaoException( - "This dao can only retrieve reference of type T2Reference.ReferenceSet"); - if (!(ref instanceof T2ReferenceImpl)) - throw new DaoException( - "Reference must be an instance of T2ReferenceImpl"); - - try { - return (ReferenceSetImpl) getHibernateTemplate().get( - ReferenceSetImpl.class, - ((T2ReferenceImpl) ref).getCompactForm()); - } catch (Exception ex) { - throw new DaoException(ex); - } - } - - @Override - @DeleteIdentifiedOperation - public boolean delete(ReferenceSet rs) throws DaoException { - if (rs.getId() == null) - throw new DaoException( - "Supplied reference set has a null ID, allocate " - + "an ID before calling the store method in the dao."); - if (!rs.getId().getReferenceType().equals(ReferenceSet)) - throw new DaoException( - "Strangely the reference set ID doesn't have type " - + "T2ReferenceType.ReferenceSet, something has probably " - + "gone badly wrong somewhere earlier!"); - if (!(rs instanceof ReferenceSetImpl)) - throw new DaoException( - "Supplied reference set not an instance of ReferenceSetImpl"); - - try { - getHibernateTemplate().delete(rs); - return true; - } catch (Exception ex) { - throw new DaoException(ex); - } - } - - @Override - @SuppressWarnings("unchecked") - @DeleteIdentifiedOperation - public synchronized void deleteReferenceSetsForWFRun(String workflowRunId) - throws DaoException { - try { - // Select all ReferenceSets for this wf run - Session session = getSession(); - Query selectQuery = session - .createQuery(GET_REFSETS_FOR_RUN); - selectQuery.setString("workflow_run_id", workflowRunId); - List<ReferenceSet> referenceSets = selectQuery.list(); - session.close(); - /* - * need to close before we do delete otherwise hibernate complains - * that two sessions are accessing collection - */ - getHibernateTemplate().deleteAll(referenceSets); - } catch (Exception ex) { - throw new DaoException(ex); - } - } -}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/3ecb1291/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/IdentifiedArrayList.java ---------------------------------------------------------------------- diff --git a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/IdentifiedArrayList.java b/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/IdentifiedArrayList.java deleted file mode 100644 index e1bbe5c..0000000 --- a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/IdentifiedArrayList.java +++ /dev/null @@ -1,252 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2007 The University of Manchester - * - * Modifications to the initial code base are copyright of their - * respective authors, or their employers as appropriate. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - ******************************************************************************/ -package net.sf.taverna.t2.reference.impl; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import net.sf.taverna.t2.reference.IdentifiedList; - -/** - * Implementation of IdentifiedList which delegates to an ArrayList for its - * storage functionality. - * - * @author Tom Oinn - * - * @param <T> - */ -public class IdentifiedArrayList<T> extends AbstractEntityImpl implements - IdentifiedList<T> { - protected List<T> listDelegate = null; - - // Constructors copied from ArrayList for convenience - public IdentifiedArrayList() { - super(); - this.listDelegate = new ArrayList<>(); - } - - public IdentifiedArrayList(Collection<T> c) { - super(); - this.listDelegate = new ArrayList<>(c); - } - - public IdentifiedArrayList(int initialCapacity) { - super(); - this.listDelegate = new ArrayList<>(initialCapacity); - } - - private void checkUndefinedId() { - if (this.getId() != null) - throw new IllegalStateException( - "Attempt made to modify a list which has already been named"); - } - - @Override - public boolean add(T e) { - checkUndefinedId(); - return listDelegate.add(e); - } - - @Override - public void add(int index, T element) { - checkUndefinedId(); - listDelegate.add(index, element); - } - - @Override - public boolean addAll(Collection<? extends T> c) { - checkUndefinedId(); - return listDelegate.addAll(c); - } - - @Override - public boolean addAll(int index, Collection<? extends T> c) { - checkUndefinedId(); - return listDelegate.addAll(index, c); - } - - @Override - public void clear() { - checkUndefinedId(); - listDelegate.clear(); - } - - @Override - public boolean contains(Object o) { - return listDelegate.contains(o); - } - - @Override - public boolean containsAll(Collection<?> c) { - return listDelegate.containsAll(c); - } - - @Override - public T get(int index) { - return listDelegate.get(index); - } - - @Override - public int indexOf(Object o) { - return listDelegate.indexOf(o); - } - - @Override - public boolean isEmpty() { - return listDelegate.isEmpty(); - } - - @Override - public Iterator<T> iterator() { - return listDelegate.iterator(); - } - - @Override - public int lastIndexOf(Object o) { - return listDelegate.lastIndexOf(o); - } - - /** - * The ListIterator can modify the list contents, so wrap the delegate's - * list iterator and use as a delegate itself, checking for null ID on - * operations which set list properties. - * - * @param iteratorDelegate - * ListIterator to wrap. - * @return wrapped ListIterator which throws IllegalStateException on calls - * which modify the list if the ID has been set to a non-null value - */ - private ListIterator<T> getCheckedListIterator( - final ListIterator<T> iteratorDelegate) { - return new ListIterator<T>() { - @Override - public void add(T e) { - checkUndefinedId(); - iteratorDelegate.add(e); - } - - @Override - public boolean hasNext() { - return iteratorDelegate.hasNext(); - } - - @Override - public boolean hasPrevious() { - return iteratorDelegate.hasPrevious(); - } - - @Override - public T next() { - return iteratorDelegate.next(); - } - - @Override - public int nextIndex() { - return iteratorDelegate.nextIndex(); - } - - @Override - public T previous() { - return iteratorDelegate.previous(); - } - - @Override - public int previousIndex() { - return iteratorDelegate.previousIndex(); - } - - @Override - public void remove() { - checkUndefinedId(); - iteratorDelegate.remove(); - } - - @Override - public void set(T e) { - checkUndefinedId(); - iteratorDelegate.set(e); - } - }; - } - - @Override - public ListIterator<T> listIterator() { - return getCheckedListIterator(listDelegate.listIterator()); - } - - @Override - public ListIterator<T> listIterator(int index) { - return getCheckedListIterator(listDelegate.listIterator(index)); - } - - @Override - public boolean remove(Object o) { - checkUndefinedId(); - return listDelegate.remove(o); - } - - @Override - public T remove(int index) { - checkUndefinedId(); - return listDelegate.remove(index); - } - - @Override - public boolean removeAll(Collection<?> c) { - checkUndefinedId(); - return listDelegate.removeAll(c); - } - - @Override - public boolean retainAll(Collection<?> c) { - checkUndefinedId(); - return listDelegate.retainAll(c); - } - - @Override - public T set(int index, T element) { - checkUndefinedId(); - return listDelegate.set(index, element); - } - - @Override - public int size() { - return listDelegate.size(); - } - - @Override - public List<T> subList(int fromIndex, int toIndex) { - return listDelegate.subList(fromIndex, toIndex); - } - - @Override - public Object[] toArray() { - return listDelegate.toArray(); - } - - @Override - public <U> U[] toArray(U[] a) { - return listDelegate.toArray(a); - } -} http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/3ecb1291/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/InMemoryErrorDocumentDao.java ---------------------------------------------------------------------- diff --git a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/InMemoryErrorDocumentDao.java b/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/InMemoryErrorDocumentDao.java deleted file mode 100644 index cb431d6..0000000 --- a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/InMemoryErrorDocumentDao.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2007 The University of Manchester - * - * Modifications to the initial code base are copyright of their - * respective authors, or their employers as appropriate. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - ******************************************************************************/ -package net.sf.taverna.t2.reference.impl; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import net.sf.taverna.t2.reference.DaoException; -import net.sf.taverna.t2.reference.ErrorDocument; -import net.sf.taverna.t2.reference.ErrorDocumentDao; -import net.sf.taverna.t2.reference.T2Reference; - -/** - * A trivial in-memory implementation of ErrorDocumentDao for either testing or - * very lightweight embedded systems. Uses a java Map as the backing store. - * - * @author Tom Oinn - */ -public class InMemoryErrorDocumentDao implements ErrorDocumentDao { - private Map<T2Reference, ErrorDocument> store; - - public InMemoryErrorDocumentDao() { - this.store = new ConcurrentHashMap<>(); - } - - @Override - public synchronized ErrorDocument get(T2Reference reference) - throws DaoException { - return store.get(reference); - } - - @Override - public synchronized void store(ErrorDocument theDoc) throws DaoException { - store.put(theDoc.getId(), theDoc); - } - - @Override - public synchronized boolean delete(ErrorDocument theDoc) - throws DaoException { - return store.remove(theDoc.getId()) != null; - } - - @Override - public synchronized void deleteErrorDocumentsForWFRun(String workflowRunId) - throws DaoException { - for (T2Reference reference : store.keySet()) - if (reference.getNamespacePart().equals(workflowRunId)) - store.remove(reference); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/3ecb1291/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/InMemoryListDao.java ---------------------------------------------------------------------- diff --git a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/InMemoryListDao.java b/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/InMemoryListDao.java deleted file mode 100644 index 112bf80..0000000 --- a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/InMemoryListDao.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2007 The University of Manchester - * - * Modifications to the initial code base are copyright of their - * respective authors, or their employers as appropriate. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - ******************************************************************************/ -package net.sf.taverna.t2.reference.impl; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import net.sf.taverna.t2.reference.DaoException; -import net.sf.taverna.t2.reference.IdentifiedList; -import net.sf.taverna.t2.reference.ListDao; -import net.sf.taverna.t2.reference.T2Reference; - -/** - * A trivial in-memory implementation of ListDao for either testing or very - * lightweight embedded systems. Uses a java Map as the backing store. - * - * @author Tom Oinn - */ -public class InMemoryListDao implements ListDao { - private Map<T2Reference, IdentifiedList<T2Reference>> store; - - public InMemoryListDao() { - this.store = new ConcurrentHashMap<>(); - } - - @Override - public synchronized IdentifiedList<T2Reference> get(T2Reference reference) - throws DaoException { - return store.get(reference); - } - - @Override - public synchronized void store(IdentifiedList<T2Reference> theList) - throws DaoException { - store.put(theList.getId(), theList); - } - - @Override - public boolean delete(IdentifiedList<T2Reference> theList) - throws DaoException { - return (store.remove(theList.getId()) != null); - } - - @Override - public synchronized void deleteIdentifiedListsForWFRun(String workflowRunId) - throws DaoException { - for (T2Reference reference : store.keySet()) - if (reference.getNamespacePart().equals(workflowRunId)) - store.remove(reference); - } -} http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/3ecb1291/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/InMemoryReferenceSetDao.java ---------------------------------------------------------------------- diff --git a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/InMemoryReferenceSetDao.java b/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/InMemoryReferenceSetDao.java deleted file mode 100644 index 6d00337..0000000 --- a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/InMemoryReferenceSetDao.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2007 The University of Manchester - * - * Modifications to the initial code base are copyright of their - * respective authors, or their employers as appropriate. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - ******************************************************************************/ -package net.sf.taverna.t2.reference.impl; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import net.sf.taverna.t2.reference.DaoException; -import net.sf.taverna.t2.reference.ReferenceSet; -import net.sf.taverna.t2.reference.ReferenceSetDao; -import net.sf.taverna.t2.reference.T2Reference; - -/** - * A trivial in-memory implementation of ReferenceSetDao for either testing or - * very lightweight embedded systems. Uses a java Map as the backing store. - * - * @author Tom Oinn - */ -public class InMemoryReferenceSetDao implements ReferenceSetDao { - private Map<T2Reference, ReferenceSet> store; - - public InMemoryReferenceSetDao() { - this.store = new ConcurrentHashMap<>(); - } - - @Override - public synchronized ReferenceSet get(T2Reference reference) - throws DaoException { - return store.get(reference); - } - - @Override - public synchronized void store(ReferenceSet refSet) throws DaoException { - store.put(refSet.getId(), refSet); - } - - @Override - public synchronized void update(ReferenceSet refSet) throws DaoException { - store.put(refSet.getId(), refSet); - } - - @Override - public synchronized boolean delete(ReferenceSet refSet) throws DaoException { - return store.remove(refSet.getId()) != null; - } - - @Override - public synchronized void deleteReferenceSetsForWFRun(String workflowRunId) - throws DaoException { - for (T2Reference reference : store.keySet()) - if (reference.getNamespacePart().equals(workflowRunId)) - store.remove(reference); - } -} http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/3ecb1291/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ListServiceImpl.java ---------------------------------------------------------------------- diff --git a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ListServiceImpl.java b/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ListServiceImpl.java deleted file mode 100644 index 76c219a..0000000 --- a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ListServiceImpl.java +++ /dev/null @@ -1,136 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2007 The University of Manchester - * - * Modifications to the initial code base are copyright of their - * respective authors, or their employers as appropriate. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - ******************************************************************************/ -package net.sf.taverna.t2.reference.impl; - -import static net.sf.taverna.t2.reference.impl.T2ReferenceImpl.getAsImpl; - -import java.util.List; - -import net.sf.taverna.t2.reference.DaoException; -import net.sf.taverna.t2.reference.IdentifiedList; -import net.sf.taverna.t2.reference.ListService; -import net.sf.taverna.t2.reference.ListServiceException; -import net.sf.taverna.t2.reference.ReferenceContext; -import net.sf.taverna.t2.reference.ReferenceServiceException; -import net.sf.taverna.t2.reference.T2Reference; - -/** - * Implementation of ListService, inject with an appropriate ListDao and - * T2ReferenceGenerator to enable. - * - * @author Tom Oinn - */ -public class ListServiceImpl extends AbstractListServiceImpl implements - ListService { - @Override - public IdentifiedList<T2Reference> getList(T2Reference id) - throws ListServiceException { - checkDao(); - try { - return listDao.get(id); - } catch (DaoException de) { - throw new ListServiceException(de); - } - } - - @Override - public IdentifiedList<T2Reference> registerEmptyList(int depth, - ReferenceContext context) throws ListServiceException { - if (depth < 1) - throw new ListServiceException( - "Can't register empty lists of depth " + depth); - checkDao(); - checkGenerator(); - T2ReferenceImpl newReference = getAsImpl(t2ReferenceGenerator - .nextListReference(false, depth, context)); - T2ReferenceListImpl newList = new T2ReferenceListImpl(); - newList.setTypedId(newReference); - try { - listDao.store(newList); - return newList; - } catch (DaoException de) { - throw new ListServiceException(de); - } - } - - @Override - public IdentifiedList<T2Reference> registerList(List<T2Reference> items, - ReferenceContext context) throws ListServiceException { - checkDao(); - checkGenerator(); - if (items.isEmpty()) - throw new ListServiceException( - "Can't register an empty list with this method," - + " use the registerEmptyList instead"); - /* - * Track whether there are any items in the collection which are or - * contain error documents. - */ - boolean containsErrors = false; - // Track depth, ensure that all items have the same depth, fail if not. - int depth = items.get(0).getDepth(); - if (depth < 0) - throw new ListServiceException( - "Can't register list of depth less than 1, but first item " - + items.get(0) + " has depth " + depth); - T2ReferenceListImpl newList = new T2ReferenceListImpl(); - int counter = 0; - for (T2Reference ref : items) { - if (ref.getDepth() != depth) - throw new ListServiceException( - "Mismatched depths in list registration; reference at index '" - + counter + "' has depth " + ref.getDepth() - + " but all preceeding items have depth " - + depth); - if (ref.containsErrors()) - // The collection's reference contains errors if any child does - containsErrors = true; - newList.add(ref); - counter++; - } - try { - T2ReferenceImpl newReference = getAsImpl(t2ReferenceGenerator - .nextListReference(containsErrors, depth + 1, context)); - newList.setTypedId(newReference); - listDao.store(newList); - return newList; - } catch (Throwable t) { - throw new ListServiceException(t); - } - } - - @Override - public boolean delete(T2Reference reference) - throws ReferenceServiceException { - checkDao(); - IdentifiedList<T2Reference> list = listDao.get(reference); - if (list == null) - return false; - return listDao.delete(list); - } - - @Override - public void deleteIdentifiedListsForWorkflowRun(String workflowRunId) - throws ReferenceServiceException { - checkDao(); - listDao.deleteIdentifiedListsForWFRun(workflowRunId); - } -} http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/3ecb1291/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceServiceImpl.java ---------------------------------------------------------------------- diff --git a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceServiceImpl.java b/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceServiceImpl.java deleted file mode 100644 index 6dc3df4..0000000 --- a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceServiceImpl.java +++ /dev/null @@ -1,731 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2007 The University of Manchester - * - * Modifications to the initial code base are copyright of their - * respective authors, or their employers as appropriate. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - ******************************************************************************/ -package net.sf.taverna.t2.reference.impl; - -import static java.lang.Float.MAX_VALUE; -import static net.sf.taverna.t2.reference.T2ReferenceType.ErrorDocument; -import static net.sf.taverna.t2.reference.T2ReferenceType.IdentifiedList; -import static net.sf.taverna.t2.reference.T2ReferenceType.ReferenceSet; -import static net.sf.taverna.t2.reference.impl.T2ReferenceImpl.getAsImpl; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import net.sf.taverna.t2.reference.ContextualizedT2Reference; -import net.sf.taverna.t2.reference.ErrorDocument; -import net.sf.taverna.t2.reference.ErrorDocumentServiceException; -import net.sf.taverna.t2.reference.ExternalReferenceSPI; -import net.sf.taverna.t2.reference.Identified; -import net.sf.taverna.t2.reference.IdentifiedList; -import net.sf.taverna.t2.reference.ListServiceException; -import net.sf.taverna.t2.reference.ReferenceContext; -import net.sf.taverna.t2.reference.ReferenceService; -import net.sf.taverna.t2.reference.ReferenceServiceException; -import net.sf.taverna.t2.reference.ReferenceSet; -import net.sf.taverna.t2.reference.ReferenceSetServiceException; -import net.sf.taverna.t2.reference.StreamToValueConverterSPI; -import net.sf.taverna.t2.reference.T2Reference; -import net.sf.taverna.t2.reference.ValueCarryingExternalReference; -import net.sf.taverna.t2.reference.ValueToReferenceConversionException; -import net.sf.taverna.t2.reference.ValueToReferenceConverterSPI; - -import org.apache.log4j.Logger; - -/** - * Implementation of ReferenceService, inject with ReferenceSetService, - * ErrorDocumentService and ListService to enable. - * - * @author Tom Oinn - * @author Alan R Williams - * @author Stuart Owen - * @author Stian Soiland-Reyes - */ -public class ReferenceServiceImpl extends AbstractReferenceServiceImpl - implements ReferenceService { - private final Logger log = Logger.getLogger(ReferenceServiceImpl.class); - - /** - * The top level registration method is used to register either as yet - * unregistered ErrorDocuments and ReferenceSets (if these are passed in and - * already have an identifier this call does nothing) and arbitrarily nested - * Lists of the same. In addition any ExternalReferenceSPI instances found - * will be wrapped in a single item ReferenceSet and registered, and any - * Throwables will be wrapped in an ErrorDocument and registered. Lists will - * be converted to IdentifiedList<T2Reference> and registered if all - * children can be (or were already) appropriately named. - * <p> - * This method is only valid on parameters of the following type : - * <ol> - * <li>{@link ReferenceSet} - registered if not already registered, - * otherwise returns existing T2Reference</li> - * <li>{@link ErrorDocument} - same behaviour as ReferenceSet</li> - * <li>{@link ExternalReferenceSPI} - wrapped in ReferenceSet, registered - * and ID returned</li> - * <li>Throwable - wrapped in ErrorDocument with no message, registered and - * ID returned</li> - * <li>List - all children are first registered, if this succeeds the list - * is itself registered as an IdentifiedList of T2Reference and its - * reference returned.</li> - * </ol> - * The exception to this is if the useConvertorSPI parameter is set to true - * - in this case any objects which do not match the above allowed list will - * be run through any available ValueToReferenceConvertorSPI instances in - * turn until one succeeds or all fail, which may result in the creation of - * ExternalReferenceSPI instances. As these can be registered such objects - * will not cause an exception to be thrown. - * - * @param o - * the object to register with the reference system, must comply - * with and will be interpreted as shown in the type list above. - * @param targetDepth - * the depth of the top level object supplied. This is needed - * when registering empty collections and error documents, - * whether as top level types or as members of a collection - * within the top level type. If registering a collection this is - * the collection depth, so a List of ReferenceSchemeSPI would be - * depth 1. Failing to specify this correctly will result in - * serious problems downstream so be careful! We can't catch all - * potential problems in this method (although some errors will - * be trapped). - * @param useConverterSPI - * whether to attempt to use the ValueToReferenceConvertorSPI - * registry (if defined and available) to map arbitrary objects - * to ExternalReferenceSPI instances on the fly. The registry of - * converters is generally injected into the implementation of - * this service. - * @param context - * ReferenceContext to use if required by component services, - * this is most likely to be used by the object to reference - * converters if engaged. - * <p> - * If the context is null a new empty reference context is - * inserted. - * @return a T2Reference to the registered object - * @throws ReferenceServiceException - * if the object type (or, for collections, the recursive type - * of its contents) is not in the allowed list or if a problem - * occurs during registration. Also thrown if attempting to use - * the converter SPI without an attached registry. - */ - @Override - public T2Reference register(Object o, int targetDepth, - boolean useConverterSPI, ReferenceContext context) - throws ReferenceServiceException { - checkServices(); - if (context == null) - context = new EmptyReferenceContext(); - if (useConverterSPI) - checkConverterRegistry(); - return getNameForObject(o, targetDepth, useConverterSPI, context); - } - - @SuppressWarnings("unchecked") - private T2Reference getNameForObject(Object o, int currentDepth, - boolean useConverterSPI, ReferenceContext context) - throws ReferenceServiceException { - if (currentDepth < 0) - throw new ReferenceServiceException("Cannot register at depth " - + currentDepth + ": " + o); - /* - * First check whether this is an Identified, and if so whether it - * already has an ID. If this is the case then return it, we assume that - * anything which has an identifier already allocated must have been - * registered (this is implicit in the contract for the various - * sub-services - */ - if (o instanceof Identified) { - Identified i = (Identified) o; - if (i.getId() != null) - return i.getId(); - } - /* - * Then check whether the item *is* a T2Reference, in which case we can - * just return it (useful for when registering lists of existing - * references) - */ - if (o instanceof T2Reference) - return (T2Reference) o; - - if (o.getClass().isArray()) { - Class<?> elementType = o.getClass().getComponentType(); - if (elementType.getCanonicalName().equals("char")) { - char[] cArray = (char[]) o; - List<Character> cList = new ArrayList<>(); - for (char c : cArray) - cList.add(new Character(c)); - o = cList; - } else if (elementType.getCanonicalName().equals("short")) { - short[] cArray = (short[]) o; - List<Short> cList = new ArrayList<>(); - for (short c : cArray) - cList.add(new Short(c)); - o = cList; - } else if (elementType.getCanonicalName().equals("int")) { - int[] cArray = (int[]) o; - List<Integer> cList = new ArrayList<>(); - for (int c : cArray) - cList.add(new Integer(c)); - o = cList; - } else if (elementType.getCanonicalName().equals("long")) { - long[] cArray = (long[]) o; - List<Long> cList = new ArrayList<>(); - for (long c : cArray) - cList.add(new Long(c)); - o = cList; - } else if (elementType.getCanonicalName().equals("float")) { - float[] cArray = (float[]) o; - List<Float> cList = new ArrayList<>(); - for (float c : cArray) - cList.add(new Float(c)); - o = cList; - } else if (elementType.getCanonicalName().equals("double")) { - double[] cArray = (double[]) o; - List<Double> cList = new ArrayList<>(); - for (double c : cArray) - cList.add(new Double(c)); - o = cList; - } else if (elementType.getCanonicalName().equals("boolean")) { - boolean[] cArray = (boolean[]) o; - List<Boolean> cList = new ArrayList<>(); - for (boolean c : cArray) - cList.add(new Boolean(c)); - o = cList; - } else if (!elementType.getCanonicalName().equals("byte")) { - // Covert arrays of objects - Object[] cArray = (Object[]) o; - List<Object> cList = new ArrayList<>(); - for (Object c : cArray) - cList.add(c); - o = cList; - } - } - - // If a Collection but not a List - if ((o instanceof Collection) && !(o instanceof List)) { - List<Object> cList = new ArrayList<>(); - cList.addAll((Collection<Object>) o); - o = cList; - } - // Next check lists. - if (o instanceof List) { - if (currentDepth < 1) - throw new ReferenceServiceException( - "Cannot register list at depth " + currentDepth); - List<?> l = (List<?>) o; - /* - * If the list is empty then register a new empty list of the - * appropriate depth and return it - */ - if (l.isEmpty()) - try { - return listService.registerEmptyList(currentDepth, context) - .getId(); - } catch (ListServiceException lse) { - throw new ReferenceServiceException(lse); - } - /* - * Otherwise construct a new list of T2Reference and register it, - * calling the getNameForObject method on all children of the list - * to construct the list of references - */ - else { - List<T2Reference> references = new ArrayList<>(); - for (Object item : l) - /* - * Recursively call this method with a depth one lower than - * the current depth - */ - references.add(getNameForObject(item, currentDepth - 1, - useConverterSPI, context)); - try { - return listService.registerList(references, context) - .getId(); - } catch (ListServiceException lse) { - throw new ReferenceServiceException(lse); - } - } - } else { - /* - * Neither a list nor an already identified object, first thing is - * to engage the converters if enabled. Only engage if we don't - * already have a Throwable or an ExternalReferenceSPI instance - */ - if (useConverterSPI && (o instanceof Throwable == false) - && (o instanceof ExternalReferenceSPI == false)) { - if (currentDepth != 0) - throw new ReferenceServiceException( - "Cannot register object " + o + " at depth " - + currentDepth); - - for (ValueToReferenceConverterSPI converter : converters) - if (converter.canConvert(o, context)) - try { - o = converter.convert(o, context); - break; - } catch (ValueToReferenceConversionException vtrce) { - /* - * Fail, but that doesn't matter at the moment as - * there may be more converters to try. - * - * TODO - log this! - */ - } - } - /* - * If the object is neither a Throwable nor an ExternalReferenceSPI - * instance at this point we should fail the registration process, - * this means either that the conversion process wasn't enabled or - * that it failed to map the object type correctly. - */ - if (!(o instanceof Throwable) - && !(o instanceof ExternalReferenceSPI)) - throw new ReferenceServiceException( - "Failed to register object " - + o - + ", found a type '" - + o.getClass().getCanonicalName() - + "' which cannot currently be registered with the reference manager"); - - // Have either a Throwable or an ExternalReferenceSPI - if (o instanceof Throwable) - // Wrap in an ErrorDocument and return the ID - try { - ErrorDocument doc = errorDocumentService.registerError( - (Throwable) o, currentDepth, context); - return doc.getId(); - } catch (ErrorDocumentServiceException edse) { - throw new ReferenceServiceException(edse); - } - if (o instanceof ExternalReferenceSPI) { - if (currentDepth != 0) - throw new ReferenceServiceException( - "Cannot register external references at depth " - + currentDepth); - try { - Set<ExternalReferenceSPI> references = new HashSet<ExternalReferenceSPI>(); - references.add((ExternalReferenceSPI) o); - ReferenceSet rs = referenceSetService.registerReferenceSet( - references, context); - return rs.getId(); - } catch (ReferenceSetServiceException rsse) { - throw new ReferenceServiceException(rsse); - } - } - } - throw new ReferenceServiceException( - "Should never see this, reference registration" - + " logic has fallen off the end of the" - + " world, check the code!"); - } - - /** - * Perform recursive identifier resolution, building a collection structure - * of Identified objects, any collection elements being IdentifiedLists of - * Identified subclasses. If the id has depth 0 this will just return the - * Identified to which that id refers. - * - * @param id - * the T2Reference to resolve - * @param ensureTypes - * a set of ExternalReferenceSPI classes, this is used to augment - * any resolved ReferenceSet instances to ensure that each one - * has at least one of the specified types. If augmentation is - * not required this can be set to null. - * @param context - * the ReferenceContext to use to resolve this and any - * recursively resolved identifiers - * <p> - * If the context is null a new EmptyReferenceContext is inserted - * in its place. - * @return fully resolved Identified subclass - this is either a (recursive) - * IdentifiedList of Identified, a ReferenceSet or an ErrorDocument - * @throws ReferenceServiceException - * if any problems occur during resolution - */ - @Override - public Identified resolveIdentifier(T2Reference id, - Set<Class<ExternalReferenceSPI>> ensureTypes, - ReferenceContext context) throws ReferenceServiceException { - checkServices(); - if (context == null) - context = new EmptyReferenceContext(); - switch (id.getReferenceType()) { - case ReferenceSet: - try { - ReferenceSet rs; - if (ensureTypes == null) - rs = referenceSetService.getReferenceSet(id); - else - rs = referenceSetService.getReferenceSetWithAugmentation( - id, ensureTypes, context); - if (rs == null) - throw new ReferenceServiceException( - "Could not find ReferenceSet " + id); - return rs; - } catch (ReferenceSetServiceException rsse) { - throw new ReferenceServiceException(rsse); - } - - case ErrorDocument: - try { - ErrorDocument ed = errorDocumentService.getError(id); - if (ed == null) - throw new ReferenceServiceException( - "Could not find ErrorDocument " + id); - return ed; - } catch (ErrorDocumentServiceException edse) { - throw new ReferenceServiceException(edse); - } - - case IdentifiedList: - try { - IdentifiedList<T2Reference> idList = listService.getList(id); - if (idList == null) - throw new ReferenceServiceException( - "Could not find IdentifiedList " + id); - /* - * Construct a new list, and populate with the result of - * resolving each ID in turn - */ - IdentifiedArrayList<Identified> newList = new IdentifiedArrayList<>(); - for (T2Reference item : idList) - newList.add(resolveIdentifier(item, ensureTypes, context)); - newList.setTypedId(getAsImpl(id)); - return newList; - } catch (ListServiceException lse) { - throw new ReferenceServiceException(lse); - } - - default: - throw new ReferenceServiceException("Unsupported ID type : " - + id.getReferenceType()); - } - } - - @Override - public Object renderIdentifier(T2Reference id, Class<?> leafClass, - ReferenceContext context) throws ReferenceServiceException { - // Check we have the services installed - checkServices(); - - // Insert an empty context if context was null - if (context == null) - context = new EmptyReferenceContext(); - // Reject if the source reference contains errors - if (id.containsErrors()) - throw new ReferenceServiceException( - "Can't render an identifier which contains errors to a POJO"); - - /* - * Attempt to find an appropriate StreamToValueConverterSPI instance to - * build the specified class - */ - StreamToValueConverterSPI<?> converter = null; - if (valueBuilders != null) - for (StreamToValueConverterSPI<?> stvc : valueBuilders) { - Class<?> builtClass = stvc.getPojoClass(); - if (leafClass.isAssignableFrom(builtClass)) { - converter = stvc; - break; - } - } - if (converter == null) - log.warn("No stream->value converters found for type '" - + leafClass.getCanonicalName() + "'"); - - // Render the identifier - return renderIdentifierInner(id, leafClass, context, converter); - } - - private Object renderIdentifierInner(T2Reference id, Class<?> leafClass, - ReferenceContext context, StreamToValueConverterSPI<?> converter) - throws ReferenceServiceException { - checkServices(); - - switch (id.getReferenceType()) { - case IdentifiedList: - try { - IdentifiedList<T2Reference> idList = listService.getList(id); - if (idList == null) - throw new ReferenceServiceException( - "Could not find IdentifiedList " + id); - List<Object> result = new ArrayList<>(); - for (T2Reference child : idList) - result.add(renderIdentifierInner(child, leafClass, context, - converter)); - return result; - } catch (ListServiceException lse) { - throw new ReferenceServiceException(lse); - } - - case ReferenceSet: - try { - ReferenceSet rs = referenceSetService.getReferenceSet(id); - if (rs == null) - throw new ReferenceServiceException( - "Could not find ReferenceSet " + id); - // Check that there are references in the set - if (rs.getExternalReferences().isEmpty()) - throw new ReferenceServiceException( - "Can't render an empty reference set to a POJO"); - /* - * If we can't directly map to an appropriate value keep track - * of the cheapest reference from which to try to build the pojo - * from a stream - */ - ExternalReferenceSPI cheapestReference = null; - float cheapestReferenceCost = MAX_VALUE; - for (ExternalReferenceSPI ers : rs.getExternalReferences()) { - if (ers instanceof ValueCarryingExternalReference<?>) { - ValueCarryingExternalReference<?> vcer = (ValueCarryingExternalReference<?>) ers; - if (leafClass.isAssignableFrom(vcer.getValueType())) - return vcer.getValue(); - } - // Got here so this wasn't an appropriate value type - if (cheapestReference == null - || ers.getResolutionCost() < cheapestReferenceCost) { - cheapestReference = ers; - cheapestReferenceCost = ers.getResolutionCost(); - } - } - if (converter != null && cheapestReference != null) - try (InputStream stream = cheapestReference - .openStream(context)) { - return converter.renderFrom(stream, - cheapestReference.getDataNature(), - cheapestReference.getCharset()); - } - } catch (Exception e) { - throw new ReferenceServiceException(e); - } - throw new ReferenceServiceException( - "No converter found, and reference set didn't contain" - + " an appropriate value carrying reference, cannot render to POJO"); - - default: - throw new ReferenceServiceException("Unsupported ID type : " - + id.getReferenceType()); - } - } - - /** - * Initiates a traversal of the specified t2reference, traversing to - * whatever level of depth is required such that all identifiers returned - * within the iterator have the specified depth. The context (i.e. the index - * path from the originally specified reference to each reference within the - * iteration) is included through use of the ContextualizedT2Reference - * wrapper class - * - * @param source - * the T2Reference from which to traverse. In general this is the - * root of a collection structure. - * @param desiredDepth - * the desired depth of all returned T2References, must be less - * than or equal to that of the source reference. - * @throws ReferenceServiceException - * if unable to create the iterator for some reason. Note that - * implementations are free to lazily perform the iteration so - * this method may succeed but the iterator produced can fail - * when used. If the iterator fails it will do so by throwing - * one of the underlying sub-service exceptions. - */ - @Override - public Iterator<ContextualizedT2Reference> traverseFrom(T2Reference source, - int desiredDepth) throws ReferenceServiceException { - checkServices(); - if (desiredDepth < 0) - throw new ReferenceServiceException( - "Cannot traverse to a negative depth"); - List<ContextualizedT2Reference> workingSet = new ArrayList<>(); - workingSet.add(new ContextualizedT2ReferenceImpl(source, new int[0])); - int currentDepth = source.getDepth(); - while (currentDepth > desiredDepth) { - List<ContextualizedT2Reference> newSet = new ArrayList<>(); - for (ContextualizedT2Reference ci : workingSet) { - T2ReferenceImpl ref = (T2ReferenceImpl) ci.getReference(); - switch (ref.getReferenceType()) { - case IdentifiedList: - try { - int position = 0; - for (T2Reference child : getListService().getList(ref)) - newSet.add(new ContextualizedT2ReferenceImpl(child, - addIndex(ci.getIndex(), position++))); - } catch (ListServiceException lse) { - throw new ReferenceServiceException(lse); - } - break; - case ReferenceSet: - throw new ReferenceServiceException( - "Should never be trying to drill inside a data document identifier"); - case ErrorDocument: - newSet.add(new ContextualizedT2ReferenceImpl(ref - .getDeeperErrorReference(), addIndex(ci.getIndex(), - 0))); - break; - default: - throw new ReferenceServiceException( - "Fallen off end of case statement, unknown reference type!"); - } - } - currentDepth--; - workingSet = newSet; - } - return workingSet.iterator(); - } - - /** - * Append to an int[] - * - * @param current - * current int[] - * @param head - * new int item to append to the current array - * @return new array of int with the head added - */ - private static int[] addIndex(int[] current, int head) { - int[] result = new int[current.length + 1]; - System.arraycopy(current, 0, result, 0, current.length); - result[current.length] = head; - return result; - } - - /** - * Parse the reference contained in the string and return a - * {@link T2Reference} with the correct properties - */ - @Override - public T2Reference referenceFromString(String reference) { - T2ReferenceImpl newRef = new T2ReferenceImpl(); - Map<String, String> parseRef = parseRef(reference); - newRef.setNamespacePart(parseRef.get("namespace")); - newRef.setLocalPart(parseRef.get("localPart")); - String type = parseRef.get("type"); - if (type.equals("ref")) { - newRef.setReferenceType(ReferenceSet); - } else if (type.equals("list")) { - newRef.setReferenceType(IdentifiedList); - newRef.setContainsErrors(Boolean.parseBoolean(parseRef.get("error"))); - newRef.setDepth(Integer.parseInt(parseRef.get("depth"))); - } else if (type.equals("error")) { - newRef.setContainsErrors(true); - newRef.setReferenceType(ErrorDocument); - newRef.setDepth(Integer.parseInt(parseRef.get("depth"))); - } else { - return null; - // should throw an error - } - - return newRef; - } - - /** - * Parse the reference and return a map with localPart, namespace, depth, - * contains errors and the type - * - * @param ref - * @return - */ - private Map<String, String> parseRef(String ref) { - String[] split = ref.split("\\?"); - /* - * get the bit before and after the final '/' ie. the local part and the - * depth, there might not be a split1[1] since it might not be a list - */ - String[] split2 = split[1].split("/"); - // get the t2:abc:// and the namespace - String[] split3 = split[0].split("//"); - // get the t2 bit and the reference type bit - String[] split4 = split3[0].split(":"); - - Map<String, String> refPartsMap = new HashMap<String, String>(); - refPartsMap.put("type", split4[1]); - refPartsMap.put("namespace", split3[1]); - refPartsMap.put("localPart", split2[0]); - - if (refPartsMap.get("type").equals("list")) { - refPartsMap.put("error", split2[1]); - refPartsMap.put("depth", split2[2]); - } - if (refPartsMap.get("type").equals("error")) - refPartsMap.put("depth", split2[1]); - - return refPartsMap; - - } - - @Override - public boolean delete(List<T2Reference> references) - throws ReferenceServiceException { - for (T2Reference reference : references) - delete(reference); - return true; - } - - @Override - public boolean delete(T2Reference reference) - throws ReferenceServiceException { - switch (reference.getReferenceType()) { - case IdentifiedList: - return listService.delete(reference); - case ReferenceSet: - return referenceSetService.delete(reference); - case ErrorDocument: - return errorDocumentService.delete(reference); - default: - throw new ReferenceServiceException("Unknown reference type!"); - } - } - - @Override - public void deleteReferencesForWorkflowRun(String workflowRunId) - throws ReferenceServiceException { - String errorString = ""; - try { - listService.deleteIdentifiedListsForWorkflowRun(workflowRunId); - } catch (ReferenceServiceException resex) { - errorString += "Failed to delete lists for workflow run: " - + workflowRunId + "."; - } - try { - referenceSetService - .deleteReferenceSetsForWorkflowRun(workflowRunId); - } catch (ReferenceServiceException resex) { - errorString += "Failed to delete reference sets for workflow run: " - + workflowRunId + "."; - } - try { - errorDocumentService - .deleteErrorDocumentsForWorkflowRun(workflowRunId); - } catch (ReferenceServiceException resex) { - errorString += "Failed to delete error documents for workflow run: " - + workflowRunId + "."; - } - if (!errorString.equals("")) - throw new ReferenceServiceException(errorString); - } -} http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/3ecb1291/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceSetAugmentorImpl.java ---------------------------------------------------------------------- diff --git a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceSetAugmentorImpl.java b/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceSetAugmentorImpl.java deleted file mode 100644 index 33c586b..0000000 --- a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceSetAugmentorImpl.java +++ /dev/null @@ -1,462 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2007 The University of Manchester - * - * Modifications to the initial code base are copyright of their - * respective authors, or their employers as appropriate. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - ******************************************************************************/ -package net.sf.taverna.t2.reference.impl; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.PriorityQueue; -import java.util.Set; - -import net.sf.taverna.t2.reference.ExternalReferenceBuilderSPI; -import net.sf.taverna.t2.reference.ExternalReferenceSPI; -import net.sf.taverna.t2.reference.ExternalReferenceTranslatorSPI; -import net.sf.taverna.t2.reference.ReferenceContext; -import net.sf.taverna.t2.reference.ReferenceSet; -import net.sf.taverna.t2.reference.ReferenceSetAugmentationException; -import net.sf.taverna.t2.reference.ReferenceSetAugmentor; -import net.sf.taverna.t2.reference.ReferenceSetAugmentorCallback; - -import org.apache.log4j.Logger; - -/** - * Implementation of ReferenceSetAugmentor using Dijkstra's shortest path - * algorithm over a type graph built from SPI instance registries of reference - * builders and reference translators. - * - * @author Tom Oinn - */ -public class ReferenceSetAugmentorImpl implements ReferenceSetAugmentor { - private final Logger log = Logger - .getLogger(ReferenceSetAugmentorImpl.class); - - /** - * A list of ExternalReferenceBuilderSPI instances used to construct - * ExternalReferenceSPI instances from byte streams - */ - private List<ExternalReferenceBuilderSPI<?>> builders; - - /** - * A list of ExternalReferenceTranslatorSPI instances used to construct - * ExternalReferenceSPI instances from existing ExternalReferenceSPI - * instances. - */ - private List<ExternalReferenceTranslatorSPI<?, ?>> translators; - - private boolean cacheValid = false; - - private final Set<Class<ExternalReferenceSPI>> knownReferenceTypes = new HashSet<>(); - @SuppressWarnings("rawtypes") - private final Map<Class<ExternalReferenceSPI>, Set<ExternalReferenceTranslatorSPI>> adjacencySets = new HashMap<>(); - private final Map<Class<ExternalReferenceSPI>, ShortestPathSolver> solvers = new HashMap<>(); - - /** - * Default constructor to make life easier when using Spring. To be - * functional this implementation should be injected with InstanceRegistry - * implementations containing lists of known implementations of the - * ExternalReferenceBuilderSPI and ExternalReferenceTranslatorSPI - * interfaces. - */ - public ReferenceSetAugmentorImpl() { - super(); - } - - public void buildersUpdated(Object service, Map<?, ?> properties) { - cacheValid = false; - } - - public void translatorsUpdated(Object service, Map<?, ?> properties) { - cacheValid = false; - } - - /** - * Inject a list containing all known implementations of - * ExternalReferenceBuilderSPI. - * - * @throws IllegalStateException - * if this has already been set, the instance registries should - * only be set on bean construction. - */ - public synchronized void setBuilders( - List<ExternalReferenceBuilderSPI<?>> builders) { - if (this.builders != null) { - log.error("Builder registry already injected, invalid operation"); - throw new IllegalStateException( - "Can't inject the external reference builder registry " - + "multiple times."); - } - - this.builders = builders; - if (log.isDebugEnabled()) { - log.debug("* Builders injected :"); - int counter = 0; - for (ExternalReferenceBuilderSPI<?> builder : builders) - log.debug("* " + (++counter) + ") " - + builder.getClass().getSimpleName() + ", builds " - + builder.getReferenceType().getSimpleName()); - } - cacheValid = false; - } - - /** - * Inject a list containing all known implementations of - * ExternalReferenceTranslatorSPI. - * - * @throws IllegalStateException - * if this has already been set, the instance registries should - * only be set on bean construction. - */ - public synchronized void setTranslators( - List<ExternalReferenceTranslatorSPI<?, ?>> translators) { - if (this.translators == null) { - this.translators = translators; - if (log.isDebugEnabled()) { - log.debug("* Translators injected :"); - int counter = 0; - for (ExternalReferenceTranslatorSPI<?, ?> translator : translators) - log.debug("* " - + (++counter) - + ") " - + translator.getClass().getSimpleName() - + ", translates " - + translator.getSourceReferenceType() - .getSimpleName() - + " to " - + translator.getTargetReferenceType() - .getSimpleName()); - } - cacheValid = false; - } else { - log.error("Translator registry already injected, invalid operation"); - throw new IllegalStateException( - "Can't inject the translator registry multiple times."); - } - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected synchronized final void update() { - if (builders == null || translators == null || cacheValid) - return; - log.debug("# Refreshing shortest path cache"); - knownReferenceTypes.clear(); - solvers.clear(); - adjacencySets.clear(); - for (ExternalReferenceBuilderSPI erb : builders) - knownReferenceTypes.add(erb.getReferenceType()); - for (ExternalReferenceTranslatorSPI ert : translators) { - knownReferenceTypes.add(ert.getSourceReferenceType()); - knownReferenceTypes.add(ert.getTargetReferenceType()); - getNeighbours(ert.getTargetReferenceType()).add(ert); - } - for (Class<ExternalReferenceSPI> type : knownReferenceTypes) - try { - solvers.put(type, new ShortestPathSolver(type)); - } catch (Throwable t) { - log.error(t); - if (t instanceof RuntimeException) - throw (RuntimeException) t; - } - log.debug("# Path cache refresh done"); - cacheValid = true; - } - - @SuppressWarnings("rawtypes") - Set<ExternalReferenceTranslatorSPI> getNeighbours( - Class<ExternalReferenceSPI> node) { - Set<ExternalReferenceTranslatorSPI> adjacentTo = adjacencySets - .get(node); - if (adjacentTo != null) - return adjacentTo; - - HashSet<ExternalReferenceTranslatorSPI> neighbours = new HashSet<>(); - adjacencySets.put(node, neighbours); - return neighbours; - } - - @Override - public final Set<ExternalReferenceSPI> augmentReferenceSet( - ReferenceSet references, - Set<Class<ExternalReferenceSPI>> targetReferenceTypes, - ReferenceContext context) throws ReferenceSetAugmentationException { - synchronized (this) { - if (!cacheValid) - update(); - } - - // Synchronize on the reference set itself - synchronized (references) { - /* - * First check whether we actually need to modify the reference set - * at all - it's perfectly valid to call the augmentor when nothing - * actually needs to be done (ideally you wouldn't do this, but it's - * likely to happen) - */ - for (ExternalReferenceSPI er : references.getExternalReferences()) - if (targetReferenceTypes.contains(er.getClass())) - return new HashSet<>(); - - // Need to perform augmentation if we reach this point - List<TranslationPath> candidatePaths = new ArrayList<>(); - for (Class<ExternalReferenceSPI> target : targetReferenceTypes) { - ShortestPathSolver solver = solvers.get(target); - if (solver == null) { - solver = new ShortestPathSolver(target); - solvers.put(target, solver); - } - if (solver != null) - for (TranslationPath path : solver.getTranslationPaths()) { - for (ExternalReferenceSPI er : references - .getExternalReferences()) - if (er.getClass().equals(path.getSourceType())) - candidatePaths.add(path); - for (TranslationPath dereferenceBasedPath : path - .getDereferenceBasedPaths(references)) - candidatePaths.add(dereferenceBasedPath); - } - } - /* - * Now add candidate paths to represent a no-translator 'direct from - * byte stream source' path for each target type compatible - * reference builder - */ - for (ExternalReferenceBuilderSPI<?> builder : builders) - if (targetReferenceTypes.contains(builder.getReferenceType())) - /* - * The builder can construct one of the target types, add - * paths for all possible pairs of 'de-reference existing - * reference' and the builder - */ - for (ExternalReferenceSPI er : references - .getExternalReferences()) { - TranslationPath newPath = new TranslationPath(); - newPath.setBuilders(builders); - newPath.setInitialBuilder(builder); - newPath.setSourceReference(er); - candidatePaths.add(newPath); - } - - /* - * Got a list of candidate paths sorted by estimated overall path - * cost - */ - Collections.sort(candidatePaths); - if (log.isDebugEnabled()) { - log.debug("Found " - + candidatePaths.size() - + " contextual translation path(s) including builder based :"); - int counter = 0; - for (TranslationPath path : candidatePaths) - log.debug(" " + (++counter) + ") " + path.toString()); - } - - if (candidatePaths.isEmpty()) { - log.warn("No candidate paths found for augmentation"); - throw new ReferenceSetAugmentationException( - "No candidate translation paths were found"); - } - - log.debug("Performing augmentation :"); - int counter = 0; - for (TranslationPath path : candidatePaths) - try { - counter++; - Set<ExternalReferenceSPI> newReferences = path - .doTranslation(references, context); - if (log.isDebugEnabled()) - log.debug(" Success (" + counter + "), created " - + printRefSet(newReferences)); - return newReferences; - } catch (Exception ex) { - log.debug(" Failed (" + counter + ")"); - log.trace(ex); - // Use next path... - } - log.warn(" No paths succeeded, augmentation failed"); - throw new ReferenceSetAugmentationException( - "All paths threw exceptions, can't perform augmentation"); - } - } - - private String printRefSet(Set<ExternalReferenceSPI> set) { - StringBuilder sb = new StringBuilder("["); - String sep = ""; - for (ExternalReferenceSPI ref : set) { - sb.append(sep).append(ref.toString()); - sep = ","; - } - return sb.append("]").toString(); - } - - @Override - public final void augmentReferenceSetAsynch(final ReferenceSet references, - final Set<Class<ExternalReferenceSPI>> targetReferenceTypes, - final ReferenceContext context, - final ReferenceSetAugmentorCallback callback) - throws ReferenceSetAugmentationException { - Runnable r = new Runnable() { - @Override - public void run() { - try { - callback.augmentationCompleted(augmentReferenceSet( - references, targetReferenceTypes, context)); - } catch (ReferenceSetAugmentationException rsae) { - callback.augmentationFailed(rsae); - } - } - }; - executeRunnable(r); - } - - /** - * Schedule a runnable for execution - current naive implementation uses a - * new thread and executes immediately, but this is where any thread pool - * logic would go if we wanted to add that. - * - * @param r - */ - private void executeRunnable(Runnable r) { - new Thread(r).start(); - } - - class ShortestPathSolver { - private Map<Class<ExternalReferenceSPI>, Class<ExternalReferenceSPI>> predecessors; - private Map<Class<ExternalReferenceSPI>, ExternalReferenceTranslatorSPI<?, ?>> translators; - private Map<Class<ExternalReferenceSPI>, Float> shortestDistances; - private final Comparator<Class<ExternalReferenceSPI>> shortestDistanceComparator = new Comparator<Class<ExternalReferenceSPI>>() { - @Override - public int compare(Class<ExternalReferenceSPI> left, - Class<ExternalReferenceSPI> right) { - float shortestDistanceLeft = shortestDistances.get(left); - float shortestDistanceRight = shortestDistances.get(right); - if (shortestDistanceLeft > shortestDistanceRight) - return +1; - if (shortestDistanceLeft < shortestDistanceRight) - return -1; - return left.getCanonicalName().compareTo( - right.getCanonicalName()); - } - }; - private final PriorityQueue<Class<ExternalReferenceSPI>> unsettledNodes = new PriorityQueue<>( - 10, shortestDistanceComparator); - private final Set<Class<ExternalReferenceSPI>> settledNodes = new HashSet<>(); - - private final List<TranslationPath> translationPaths = new ArrayList<>(); - - public List<TranslationPath> getTranslationPaths() { - return this.translationPaths; - } - - public ShortestPathSolver(Class<ExternalReferenceSPI> targetType) { - log.debug("# Constructing shortest paths to '" - + targetType.getSimpleName() + "'"); - predecessors = new HashMap<>(); - translators = new HashMap<>(); - shortestDistances = new HashMap<>(); - setShortestDistance(targetType, 0.0f); - unsettledNodes.add(targetType); - while (!unsettledNodes.isEmpty()) { - Class<ExternalReferenceSPI> u = extractMin(); - settledNodes.add(u); - relaxNeighbours(u); - } - for (Class<ExternalReferenceSPI> c : settledNodes) - if (!c.equals(targetType)) { - // Don't calculate a path to itself! - TranslationPath p = new TranslationPath(); - p.setBuilders(builders); - Class<ExternalReferenceSPI> node = c; - while (predecessors.get(node) != null) { - p.pathSteps().add(translators.get(node)); - // Recurse, should terminate at the target type - node = predecessors.get(node); - } - translationPaths.add(p); - } - Collections.sort(translationPaths); - if (translationPaths.isEmpty()) - log.debug("# no paths discovered, type not reachable through translation"); - else if (log.isDebugEnabled()) { - log.debug("# found " + translationPaths.size() - + " distinct path(s) :"); - int counter = 0; - for (TranslationPath path : translationPaths) - log.debug("# " + (++counter) + ") " + path); - } - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private void relaxNeighbours(Class<ExternalReferenceSPI> u) { - log.trace("# relaxing node " + u.getSimpleName()); - Set<Class<ExternalReferenceSPI>> alreadySeen = new HashSet<>(); - for (ExternalReferenceTranslatorSPI ert : getNeighbours(u)) { - // all the translators that translate *to* u - Class<ExternalReferenceSPI> v = ert.getSourceReferenceType(); - log.trace("# translator found from from '" + v + "' : " - + ert.getClass().getSimpleName()); - if (!alreadySeen.contains(v) && !isSettled(v)) { - /* - * Avoid duplicate edges, always take the first one where - * such duplicates exist - */ - alreadySeen.add(v); - if (getShortestDistance(v) > getShortestDistance(u) - + ert.getTranslationCost()) { - setShortestDistance( - v, - getShortestDistance(u) - + ert.getTranslationCost()); - setPredecessor(v, u, ert); - unsettledNodes.add(v); - } - } - } - } - - private boolean isSettled(Class<ExternalReferenceSPI> node) { - return settledNodes.contains(node); - } - - private void setShortestDistance(Class<ExternalReferenceSPI> node, - float distance) { - shortestDistances.put(node, distance); - } - - private float getShortestDistance(Class<ExternalReferenceSPI> node) { - Float d = shortestDistances.get(node); - return (d == null) ? Float.MAX_VALUE : d; - } - - private Class<ExternalReferenceSPI> extractMin() { - return unsettledNodes.poll(); - } - - private void setPredecessor(Class<ExternalReferenceSPI> child, - Class<ExternalReferenceSPI> parent, - ExternalReferenceTranslatorSPI<?, ?> translator) { - predecessors.put(child, parent); - translators.put(child, translator); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/3ecb1291/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceSetImpl.java ---------------------------------------------------------------------- diff --git a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceSetImpl.java b/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceSetImpl.java deleted file mode 100644 index 437cd1d..0000000 --- a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceSetImpl.java +++ /dev/null @@ -1,123 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2007 The University of Manchester - * - * Modifications to the initial code base are copyright of their - * respective authors, or their employers as appropriate. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - ******************************************************************************/ -package net.sf.taverna.t2.reference.impl; - -import java.util.Set; - -import net.sf.taverna.t2.reference.ExternalReferenceSPI; -import net.sf.taverna.t2.reference.ReferenceSet; -import net.sf.taverna.t2.reference.h3.HibernateMappedEntity; - -/** - * An implementation of ReferenceSet with the additional methods and metadata - * required by Hibernate3 to allow it to be persisted in a relational store. As - * with everything else in this package you shouldn't be using this class - * directly! Instead of this class you should use the registration methods on - * {@link net.sf.taverna.t2.reference.ReferenceSetService}, implementations of - * that interface will handle the construction of ReferenceSet implementations - * (including this one). - * - * @author Tom Oinn - */ -public class ReferenceSetImpl extends AbstractEntityImpl implements - ReferenceSet, HibernateMappedEntity { - private Set<ExternalReferenceSPI> externalReferences; - private Long approximateSizeInBytes = new Long(-1); - - /** - * Construct a new ReferenceSetImpl with the given set of external - * references and identifier. - * - * @param references - * the set of ExternalReferenceSPI which this reference set - * should contain initially - * @param id - * the T2Reference to use, must be an instance of - * ReferenceSetT2ReferenceImpl so hibernate can make use of it as - * a compound primary key component - */ - public ReferenceSetImpl(Set<ExternalReferenceSPI> references, - T2ReferenceImpl id) { - setTypedId(id); - this.externalReferences = references; - - // Should be at least one - otherwise we cannot calculate the data size - if (externalReferences != null && externalReferences.size() > 0) { - // Just take the first ExternalReferenceSPI returned - ExternalReferenceSPI externalReferenceSPI = externalReferences - .toArray(new ExternalReferenceSPI[0])[0]; - approximateSizeInBytes = externalReferenceSPI - .getApproximateSizeInBytes(); - } - } - - /** - * Default constructor, used by Hibernate when reconstructing this bean from - * the database. If you call this directly from your code you must then call - * both {@link #setExternalReferences(Set)} and - * {@link #setId(T2ReferenceImpl)} before any use of the reference set. If - * you're not writing the reference manager implementation you shouldn't be - * using this class anyway. - */ - public ReferenceSetImpl() { - // - } - - /** - * For debugging purposes, prints a summary of the contents and identifier - * of this reference set. - * - * @return human readable string representation of this object. This is not - * regarded as 'stable' and should not be parsed for any reason! - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getId()).append(" [").append(externalReferences.size()) - .append("]\n"); - for (ExternalReferenceSPI ref : externalReferences) - sb.append(" ").append(ref).append("\n"); - return sb.toString(); - - } - - @Override - public Set<ExternalReferenceSPI> getExternalReferences() { - return externalReferences; - } - - /** - * This method is only ever called from within Hibernate, and is used to - * initialize the set of external references. - */ - public void setExternalReferences(Set<ExternalReferenceSPI> newReferences) { - this.externalReferences = newReferences; - } - - public void setApproximateSizeInBytes(Long sizeInBytes) { - this.approximateSizeInBytes = sizeInBytes; - } - - @Override - public Long getApproximateSizeInBytes() { - return approximateSizeInBytes; - } -} http://git-wip-us.apache.org/repos/asf/incubator-taverna-engine/blob/3ecb1291/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceSetServiceImpl.java ---------------------------------------------------------------------- diff --git a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceSetServiceImpl.java b/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceSetServiceImpl.java deleted file mode 100644 index 7f04709..0000000 --- a/taverna-reference-impl/src/main/java/net/sf/taverna/t2/reference/impl/ReferenceSetServiceImpl.java +++ /dev/null @@ -1,153 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2007 The University of Manchester - * - * Modifications to the initial code base are copyright of their - * respective authors, or their employers as appropriate. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - ******************************************************************************/ -package net.sf.taverna.t2.reference.impl; - -import static net.sf.taverna.t2.reference.impl.T2ReferenceImpl.getAsImpl; - -import java.net.URI; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.WeakHashMap; - -import net.sf.taverna.t2.reference.DaoException; -import net.sf.taverna.t2.reference.ExternalReferenceSPI; -import net.sf.taverna.t2.reference.ReferenceContext; -import net.sf.taverna.t2.reference.ReferenceServiceException; -import net.sf.taverna.t2.reference.ReferenceSet; -import net.sf.taverna.t2.reference.ReferenceSetAugmentationException; -import net.sf.taverna.t2.reference.ReferenceSetService; -import net.sf.taverna.t2.reference.ReferenceSetServiceException; -import net.sf.taverna.t2.reference.T2Reference; - -/** - * Implementation of ReferenceSetService, inject with an appropriate - * ReferenceSetDao to enable. Implements translation functionality as long as an - * appropriate ReferenceSetAugmentor implementation is injected. - * - * @author Tom Oinn - */ -public class ReferenceSetServiceImpl extends AbstractReferenceSetServiceImpl - implements ReferenceSetService { - @Override - public ReferenceSet getReferenceSet(T2Reference id) - throws ReferenceSetServiceException { - checkDao(); - try { - return referenceSetDao.get(id); - } catch (DaoException de) { - throw new ReferenceSetServiceException(de); - } - } - - private Map<URI,Object> locks = new WeakHashMap<>(); - - private Object getLock(T2Reference id) { - URI uri = id.toUri(); - synchronized (locks) { - Object lock = locks.get(uri); - if (lock == null) { - lock = new Object(); - locks.put(uri, lock); - } - return lock; - } - } - - @Override - public ReferenceSet getReferenceSetWithAugmentation(T2Reference id, - Set<Class<ExternalReferenceSPI>> ensureTypes, - ReferenceContext context) throws ReferenceSetServiceException { - checkDao(); - checkAugmentor(); - if (context == null) - context = new EmptyReferenceContext(); - // Obtain the reference set - - try { - /* - * Synchronize on the reference set, should ensure that we don't - * have multiple concurrent translations assuming that Hibernate - * retrieves the same entity each time. Except we have to - * synchronize on the reference, and in fact we have to synchronize - * on the URI form. - */ - synchronized (getLock(id)) { - ReferenceSet rs = getReferenceSet(id); - Set<ExternalReferenceSPI> newReferences = referenceSetAugmentor - .augmentReferenceSet(rs, ensureTypes, context); - if (!newReferences.isEmpty()) { - /* - * Write back changes to the store if we got here, this can - * potentially throw an unsupported operation exception in - * which case we have to fail the augmentation. - */ - try { - rs.getExternalReferences().addAll(newReferences); - } catch (RuntimeException re) { - throw new ReferenceSetAugmentationException( - "Can't add new references back into existing reference set instance"); - } - referenceSetDao.update(rs); - } - return rs; - } - } catch (ReferenceSetAugmentationException rsae) { - throw new ReferenceSetServiceException(rsae); - } - } - - @Override - public ReferenceSet registerReferenceSet( - Set<ExternalReferenceSPI> references, ReferenceContext context) - throws ReferenceSetServiceException { - checkDao(); - checkGenerator(); - - ReferenceSetImpl rsi = new ReferenceSetImpl(new HashSet<>(references), - getAsImpl(t2ReferenceGenerator - .nextReferenceSetReference(context))); - - try { - referenceSetDao.store(rsi); - return rsi; - } catch (DaoException de) { - throw new ReferenceSetServiceException(de); - } - } - - @Override - public boolean delete(T2Reference reference) - throws ReferenceServiceException { - checkDao(); - ReferenceSet set = referenceSetDao.get(reference); - if (set == null) - return false; - return referenceSetDao.delete(set); - } - - @Override - public void deleteReferenceSetsForWorkflowRun(String workflowRunId) - throws ReferenceServiceException { - checkDao(); - referenceSetDao.deleteReferenceSetsForWFRun(workflowRunId); - } -}
