incubator-oodt-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bfos...@apache.org
Subject svn commit: r1002752 [8/9] - in /incubator/oodt/trunk/catalog: ./ .externalToolBuilders/ .settings/ src/ src/main/ src/main/assembly/ src/main/bin/ src/main/java/ src/main/java/gov/ src/main/java/gov/nasa/ src/main/java/gov/nasa/jpl/ src/main/java/gov/...
Date Wed, 29 Sep 2010 17:19:15 GMT
Added: incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/system/impl/CatalogServiceClientFactory.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/system/impl/CatalogServiceClientFactory.java?rev=1002752&view=auto
==============================================================================
--- incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/system/impl/CatalogServiceClientFactory.java (added)
+++ incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/system/impl/CatalogServiceClientFactory.java Wed Sep 29 17:19:09 2010
@@ -0,0 +1,64 @@
+/*
+ * 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.oodt.cas.catalog.system.impl;
+
+//OODT imports
+import org.apache.oodt.cas.catalog.server.channel.CommunicationChannelClientFactory;
+import org.apache.oodt.cas.catalog.system.CatalogServiceFactory;
+
+//Spring imports
+import org.springframework.beans.factory.annotation.Required;
+
+//OODT imports
+
+/**
+ * @author bfoster
+ * @version $Revision$
+ *
+ * <p>
+ * A Factory for CatalogServiceClient
+ * <p>
+ */
+public class CatalogServiceClientFactory implements CatalogServiceFactory {
+	
+	protected CommunicationChannelClientFactory communicationChannelClientFactory;
+	protected int autoPagerSize;
+	
+	public CatalogServiceClientFactory() {
+		this.autoPagerSize = 500;
+	}
+	
+	public CatalogServiceClient createCatalogService() {
+		return new CatalogServiceClient(this.communicationChannelClientFactory.createCommunicationChannelClient(), this.autoPagerSize);
+	}
+	
+	@Required
+	public void setCommunicationChannelClientFactory(CommunicationChannelClientFactory communicationChannelClientFactory) {
+		this.communicationChannelClientFactory = communicationChannelClientFactory;
+	}
+	
+	@Required
+	public void setAutoPagerSize(int autoPagerSize) {
+		if (autoPagerSize > 0)
+			this.autoPagerSize = autoPagerSize;
+	}
+	
+	public String getServerUrl() {
+		return this.communicationChannelClientFactory.getServerUrl();
+	}
+
+}

Added: incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/system/impl/CatalogServiceLocal.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/system/impl/CatalogServiceLocal.java?rev=1002752&view=auto
==============================================================================
--- incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/system/impl/CatalogServiceLocal.java (added)
+++ incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/system/impl/CatalogServiceLocal.java Wed Sep 29 17:19:09 2010
@@ -0,0 +1,1198 @@
+/*
+ * 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.oodt.cas.catalog.system.impl;
+
+//JDK imports
+import java.io.File;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+//OODT imports
+import org.apache.oodt.cas.catalog.exception.CatalogDictionaryException;
+import org.apache.oodt.cas.catalog.exception.CatalogException;
+import org.apache.oodt.cas.catalog.exception.CatalogIndexException;
+import org.apache.oodt.cas.catalog.exception.CatalogServiceException;
+import org.apache.oodt.cas.catalog.mapping.IngestMapper;
+import org.apache.oodt.cas.catalog.metadata.TransactionalMetadata;
+import org.apache.oodt.cas.catalog.page.CatalogReceipt;
+import org.apache.oodt.cas.catalog.page.Page;
+import org.apache.oodt.cas.catalog.page.PageInfo;
+import org.apache.oodt.cas.catalog.page.ProcessedPageInfo;
+import org.apache.oodt.cas.catalog.page.QueryPager;
+import org.apache.oodt.cas.catalog.page.TransactionReceipt;
+import org.apache.oodt.cas.catalog.query.QueryExpression;
+import org.apache.oodt.cas.catalog.query.QueryLogicalGroup;
+import org.apache.oodt.cas.catalog.query.WrapperQueryExpression;
+import org.apache.oodt.cas.catalog.repository.CatalogRepository;
+import org.apache.oodt.cas.catalog.struct.Dictionary;
+import org.apache.oodt.cas.catalog.struct.Index;
+import org.apache.oodt.cas.catalog.struct.TransactionId;
+import org.apache.oodt.cas.catalog.struct.TransactionIdFactory;
+import org.apache.oodt.cas.catalog.system.Catalog;
+import org.apache.oodt.cas.catalog.system.CatalogService;
+import org.apache.oodt.cas.catalog.util.PluginURL;
+import org.apache.oodt.cas.catalog.util.QueryUtils;
+import org.apache.oodt.cas.metadata.Metadata;
+
+/**
+ * @author bfoster
+ * @version $Revision$
+ *
+ * <p>
+ * A Calatog Service that manages Metadata via one or more underlying Catalogs
+ * <p>
+ */
+public class CatalogServiceLocal implements CatalogService {
+	
+	private static Logger LOG = Logger.getLogger(CatalogServiceLocal.class.getName());
+	
+	protected Set<Catalog> catalogs;
+	protected ReadWriteLock catalogsLock;
+	protected CatalogRepository catalogRepository;
+	protected IngestMapper ingestMapper;
+	protected ReadWriteLock ingestMapperLock;
+	protected boolean restrictQueryPermissions;
+	protected boolean restrictIngestPermissions;
+	protected TransactionIdFactory transactionIdFactory;
+	protected File pluginStorageDir;
+	protected boolean oneCatalogFailsAllFail;
+	protected boolean simplifyQueries;
+	
+	public CatalogServiceLocal(CatalogRepository catalogRepository, IngestMapper ingestMapper, File pluginStorageDir, TransactionIdFactory transactionIdFactory, boolean restrictQueryPermissions, boolean restrictIngestPermissions, boolean oneCatalogFailsAllFail, boolean simplifyQueries) throws InstantiationException {
+		try {
+			this.catalogs = new HashSet<Catalog>();
+			this.catalogsLock = new ReentrantReadWriteLock();
+			this.ingestMapperLock = new ReentrantReadWriteLock();
+			this.setPluginStorageDir(pluginStorageDir);
+			this.setRestrictQueryPermissions(restrictQueryPermissions);
+			this.setRestrictIngestPermissions(restrictIngestPermissions);
+			this.setTransactionIdFactory(transactionIdFactory);
+			this.setIngestMapper(ingestMapper);
+			this.setCatalogRepository(catalogRepository);	
+			this.oneCatalogFailsAllFail = oneCatalogFailsAllFail;
+			this.simplifyQueries = simplifyQueries;
+		}catch (Exception e) {
+			e.printStackTrace();
+			throw new InstantiationException(e.getMessage());
+		}
+	}
+	
+	/**
+	 * Set the CatalogRepository for this CatalogService, with replace existing CatalogRepository
+	 * and immediately load all Catalogs from it.
+	 * @param repository The CatalogRepository to be used by this CatalogService
+	 * @throws CatalogServiceException On Error loading given CatalogRepository
+	 */
+	protected void setCatalogRepository(CatalogRepository catalogRepository) throws CatalogServiceException {
+		if (catalogRepository != null) {
+			this.catalogsLock.writeLock().lock();
+			CatalogRepository backupRepository = null;
+			Set<Catalog> backupCatalogs = null;
+			try {
+				LOG.log(Level.INFO, "Using CatalogRepository '" + catalogRepository.getClass().getName() + "'");
+				backupRepository = this.catalogRepository;
+				backupCatalogs = new HashSet<Catalog>(this.catalogs);
+				LOG.log(Level.INFO, "Loading Catalogs from CatalogRepository . . .");
+				this.catalogs = catalogRepository.deserializeAllCatalogs();
+				LOG.log(Level.INFO, "Loaded Catalogs: '" + this.catalogs + "'");
+				this.catalogRepository = catalogRepository;
+			}catch (Exception e) {
+				this.catalogs = backupCatalogs;
+				this.catalogRepository = backupRepository;
+				throw new CatalogServiceException("Failed to set CatalogRepository '" + catalogRepository + "', reverting back to original settings : " + e.getMessage(), e);
+			}finally {
+				this.catalogsLock.writeLock().unlock();
+			}
+		}else {
+			throw new CatalogServiceException("Cannot add NULL CatalogRepository to CatalogService, reverting back to original settings");
+		}
+	}
+
+	protected void setIngestMapper(IngestMapper ingestMapper) {
+		this.ingestMapperLock.writeLock().lock();
+		try {
+			LOG.log(Level.INFO, "Using IngestMapper '" + ingestMapper.getClass().getName() + "'");
+			this.ingestMapper = ingestMapper;
+		}catch (Exception e) {
+			LOG.log(Level.SEVERE, "Failed to set ingest mapper : " + e.getMessage(), e);
+		}finally {
+			this.ingestMapperLock.writeLock().unlock();
+		}
+	}
+
+	public void shutdown() throws CatalogServiceException {
+		this.catalogsLock.writeLock().lock();
+		this.ingestMapperLock.writeLock().lock();
+	}
+	
+	/**
+	 * Returns true if this CatalogService is restricting any queries
+	 * from being made to the Catalogs it is managing
+	 * @return True is restricting queries, false if restriction is
+	 * on a per Catalog bases.
+	 */
+	public boolean isRestrictQueryPermissions() {
+		return this.restrictIngestPermissions;
+	}
+
+	/**
+	 * Modify this CatalogServices query restriction, default is false.
+	 * @param restrictQueryPermissions True to block all querys to managing
+	 * Catalogs or false to leave it at a per Catalog bases.
+	 */
+	protected void setRestrictQueryPermissions(boolean restrictQueryPermissions) {
+		this.restrictQueryPermissions = restrictQueryPermissions;
+	}
+
+	/**
+	 * Returns true if this CatalogService is restricting any ingestions
+	 * from being made to the Catalogs it is managing
+	 * @return True is restricting ingestions, false if restriction is
+	 * on a per Catalog bases.
+	 */
+	public boolean isRestrictIngestPermissions() {
+		return this.restrictIngestPermissions;
+	}
+
+	/**
+	 * Modify this CatalogServices ingest restriction, default is false.
+	 * @param restrictIngestPermissions True to block all ingestions to managing
+	 * Catalogs or false to leave it at a per Catalog bases.
+	 */
+	protected void setRestrictIngestPermissions(boolean restrictIngestPermissions) {
+		this.restrictIngestPermissions = restrictIngestPermissions;
+	}
+
+	/**
+	 * 
+	 * @param transactionIdClass
+	 */
+	protected void setTransactionIdFactory(
+			TransactionIdFactory transactionIdFactory) {
+		this.transactionIdFactory = transactionIdFactory;
+	}
+	
+	public void addCatalog(String catalogId, Index index) throws CatalogServiceException {
+		if (!this.containsCatalog(catalogId)) {
+			try {
+				this.replaceCatalog(new Catalog(catalogId, index, null, false, false));
+			}catch (Exception e) {
+				
+			}
+		} else {
+			LOG.log(Level.WARNING, "Attempt to override an existing catalog '" + catalogId + "' already used in CatalogService, remedy and retry add -- no changes took place!");
+		}
+	}
+	
+	public void addCatalog(String catalogId, Index index, List<Dictionary> dictionaries) throws CatalogServiceException {
+		if (!this.containsCatalog(catalogId)) {
+			try {
+				this.replaceCatalog(new Catalog(catalogId, index, dictionaries, false, false));
+			}catch (Exception e) {
+				
+			}
+		} else {
+			LOG.log(Level.WARNING, "Attempt to override an existing catalog '" + catalogId + "' already used in CatalogService, remedy and retry add -- no changes took place!");
+		}
+	}
+
+	public void addCatalog(String catalogId, Index index, List<Dictionary> dictionaries, boolean restrictQueryPermission, boolean restrictIngestPermission) throws CatalogServiceException {
+		if (!this.containsCatalog(catalogId)) {
+			try {
+				this.replaceCatalog(new Catalog(catalogId, index, dictionaries, restrictQueryPermission, restrictIngestPermission));
+			}catch (Exception e) {
+				
+			}
+		} else {
+			LOG.log(Level.WARNING, "Attempt to override an existing catalog '" + catalogId + "' already used in CatalogService, remedy and retry add -- no changes took place!");
+		}
+	}
+
+	public void addDictionary(String catalogId, Dictionary dictionary) throws CatalogServiceException {
+		if (this.containsCatalog(catalogId)) {
+			Set<Catalog> backupCatalogs = null;
+			this.catalogsLock.writeLock().lock();
+			try {
+				backupCatalogs = new HashSet<Catalog>(this.catalogs);
+				for (Catalog catalog : this.catalogs) {
+					if (catalog.getId().equals(catalogId)) {
+						catalog.addDictionary(dictionary);
+						this.catalogRepository.serializeCatalog(catalog);
+						break;
+					}
+				}
+			}catch (Exception e) {
+				this.catalogs = backupCatalogs;
+				throw new CatalogServiceException("Failed to serialize Catalog '" + catalogId + "' -- if CatalogService goes down, Catalog will have to be readded : " + e.getMessage(), e);
+			}finally {
+				this.catalogsLock.writeLock().unlock();
+			}
+		} else {
+			LOG.log(Level.WARNING, "Attempt to change an existing catalog '" + catalogId + "' already used in CatalogService, remedy and retry add -- no changes took place!");
+		}
+	}
+	
+	public void replaceDictionaries(String catalogId, List<Dictionary> dictionaries) throws CatalogServiceException {
+		this.modifyCatalog(catalogId, dictionaries, null, null, null);
+	}
+
+	public void replaceIndex(String catalogId, Index index) throws CatalogServiceException {
+		this.modifyCatalog(catalogId, null, index, null, null);
+	}
+
+	public void modifyIngestPermission(String catalogId, boolean restrictIngestPermission) throws CatalogServiceException {
+		this.modifyCatalog(catalogId, null, null, null, restrictIngestPermission);
+	}
+	
+	public void modifyQueryPermission(String catalogId, boolean restrictQueryPermission) throws CatalogServiceException {
+		this.modifyCatalog(catalogId, null, null, restrictQueryPermission, null);
+	}
+	
+	protected void modifyCatalog(String catalogId, List<Dictionary> dictionaries, Index index, Boolean restrictQueryPermission, Boolean restrictIngestPermission) throws CatalogServiceException {
+		if (this.containsCatalog(catalogId)) {
+			Set<Catalog> backupCatalogs = null;
+			this.catalogsLock.writeLock().lock();
+			try {
+				backupCatalogs = new HashSet<Catalog>(this.catalogs);
+				for (Catalog catalog : this.catalogs) {
+					if (catalog.getId().equals(catalogId)) {
+						if (dictionaries != null)
+							catalog.setDictionaries(dictionaries);
+						if (index != null)
+							catalog.setIndex(index);
+						if (restrictQueryPermission != null)
+							catalog.setRestrictQueryPermissions(restrictQueryPermissions);
+						if (restrictIngestPermission != null)
+							catalog.setRestrictIngestPermissions(restrictIngestPermissions);
+						this.catalogRepository.serializeCatalog(catalog);
+						break;
+					}
+				}
+			}catch (Exception e) {
+				this.catalogs = backupCatalogs;
+				throw new CatalogServiceException("Failed to serialize Catalog '" + catalogId + "' -- if CatalogService goes down, Catalog will have to be readded : " + e.getMessage(), e);
+			}finally {
+				this.catalogsLock.writeLock().unlock();
+			}
+		}
+	}
+
+	protected boolean containsCatalog(String catalogId) throws CatalogServiceException {
+		this.catalogsLock.readLock().lock();
+		try {
+			return this.catalogs.contains(catalogId);
+		}catch (Exception e) {
+			throw new CatalogServiceException("Failed to check if catalog '" + catalogId + "' has already been added to this CatalogService : " + e.getMessage(), e);
+		}finally {
+			this.catalogsLock.readLock().unlock();
+		}
+	}
+	
+	/**
+	 * Ability to dynamically add a Catalog to this CatalogService for managing
+	 * @param catalog Catalog for this CatalogService to manage
+	 * @return True if catalogs where added to list
+	 * @throws CatalogServiceException If one of the adding Catalog
+	 * URNs equals that of an existing Catalog. 
+	 */	
+	public void addCatalog(Catalog catalog) throws CatalogServiceException {
+		if (!this.containsCatalog(catalog.getId()))
+			this.replaceCatalog(catalog);
+		else
+			LOG.log(Level.WARNING, "Attempt to override an existing catalog '" + catalog + "' already used in CatalogService, remedy and retry add -- no changes took place!");
+	}
+	
+	/**
+	 * Ability to dynamically add a Catalog to this CatalogService for managing
+	 * @param catalog Catalog for this CatalogService to manage
+	 * @param allowOverride True to allow adding Catalog to override existing Catalog with same URN
+	 * @throws CatalogServiceException When allowOverride=false and one of the adding Catalog
+	 * URNs equals that of an existing Catalog. 
+	 */
+	public void replaceCatalog(Catalog catalog) throws CatalogServiceException {
+		Set<Catalog> backupCatalogs = null;
+		this.catalogsLock.writeLock().lock();
+		try {
+			backupCatalogs = new HashSet<Catalog>(this.catalogs);
+			this.catalogs.remove(catalog);
+			this.catalogs.add(catalog);
+			this.catalogRepository.serializeCatalog(catalog);
+		}catch (Exception e) {
+			this.catalogs = backupCatalogs;
+			throw new CatalogServiceException("Failed to serialize Catalog '" + catalog + "' -- if CatalogService goes down, Catalog will have to be readded : " + e.getMessage(), e);
+		}finally {
+			this.catalogsLock.writeLock().unlock();
+		}
+	}
+	
+	public void removeCatalog(String catalogUrn) throws CatalogServiceException {
+		this.removeCatalog(catalogUrn, false);
+	}
+	
+	/**
+	 * 
+	 * @param catalogUrn
+	 * @throws CatalogServiceException
+	 */
+	public void removeCatalog(String catalogId, boolean preserveMapping) throws CatalogServiceException {
+			this.catalogsLock.readLock().lock();
+			Catalog rmCatalog = null;
+			try {
+				for (Catalog catalog : this.catalogs) {
+					if (catalog.getId().equals(catalogId)) {
+						rmCatalog = catalog;
+						break;
+					}
+				}
+			}catch (Exception e) {
+				throw new CatalogServiceException("Failed to find catalog object for catalog URN '" + catalogId + "' : " + e.getMessage(), e);
+			}finally {
+				this.catalogsLock.readLock().unlock();
+			}
+			
+			if (rmCatalog != null) {
+				this.catalogsLock.writeLock().lock();
+				try {
+					LOG.log(Level.INFO, "Removing catalog '" + rmCatalog + "'");
+					this.catalogs.remove(rmCatalog);
+					this.catalogRepository.deleteSerializedCatalog(catalogId);
+					if (!preserveMapping) {
+						this.ingestMapperLock.writeLock().lock();
+						try {
+							LOG.log(Level.INFO, "Deleting all index mappings for catalog '" + rmCatalog + "'");
+							this.ingestMapper.deleteAllMappingsForCatalog(catalogId);
+						}catch (Exception e) {
+							throw e;
+						}finally {
+							this.ingestMapperLock.writeLock().unlock();
+						}
+					}
+				}catch (Exception e) {
+					throw new CatalogServiceException("Failed to remove Catalog '" + catalogId + "' from this CatalogService");
+				}finally {
+					this.catalogsLock.writeLock().unlock();
+				}
+			}else {
+				LOG.log(Level.WARNING, "Catalog '" + catalogId + "' is not currently managed by this CatalogService");
+			}
+	}
+	
+	public void setPluginStorageDir(File pluginStorageDir) {
+		this.pluginStorageDir = pluginStorageDir;
+		this.pluginStorageDir.mkdirs();
+	}
+	
+	public URL getPluginStorageDir() throws CatalogServiceException {
+		try {
+			return new URL("file://" + this.pluginStorageDir.getAbsolutePath());
+		}catch (Exception e) {
+			throw new CatalogServiceException("Failed to get plugin storage dir directory : " + e.getMessage(), e);
+		}
+	}
+	
+	public List<PluginURL> getPluginUrls() throws CatalogServiceException {
+		try {
+			return this.catalogRepository.deserializePluginURLs();
+		}catch (Exception e) {
+			throw new CatalogServiceException("", e);
+		}
+	}
+	
+	public void addPluginUrls(List<PluginURL> urls) throws CatalogServiceException {
+		try {
+			List<PluginURL> currentUrls = new Vector<PluginURL>(this.catalogRepository.deserializePluginURLs());
+			currentUrls.addAll(urls);
+			this.catalogRepository.serializePluginURLs(currentUrls);
+		}catch (Exception e) {
+			throw new CatalogServiceException("", e);
+		}
+	}
+	
+	/**
+	 * 
+	 * @return
+	 * @throws CatalogServiceException
+	 */
+	public Set<Catalog> getCurrentCatalogList() throws CatalogServiceException {
+		this.catalogsLock.readLock().lock();
+		try {
+			return new HashSet<Catalog>(this.catalogs);
+		}catch (Exception e) {
+			throw new CatalogServiceException("Failed to get current catalog list : " + e.getMessage(), e);
+		}finally {
+			this.catalogsLock.readLock().unlock();
+		}
+	}
+	
+	protected Catalog getCatalog(String catalogUrn) throws CatalogServiceException {
+		this.catalogsLock.readLock().lock();
+		try {
+			for (Catalog catalog : this.catalogs)
+				if (catalog.getId().equals(catalogUrn))
+					return catalog;
+			return null;
+		}catch (Exception e) {
+			throw new CatalogServiceException("Failed to get catalog catalog '" +  catalogUrn + "' : " + e.getMessage(), e);
+		}finally {
+			this.catalogsLock.readLock().unlock();
+		}
+	}
+	
+	/**
+	 * 
+	 * @return
+	 * @throws CatalogServiceException
+	 */
+	public Set<String> getCurrentCatalogIds() throws CatalogServiceException {
+		this.catalogsLock.readLock().lock();
+		try {
+			Set<String> catalogIds = new HashSet<String>();
+			for (Catalog catalog : this.catalogs) 
+				catalogIds.add(catalog.getId());
+			return catalogIds;
+		}catch (Exception e) {
+			throw new CatalogServiceException("Failed to get current catalog ids list : " + e.getMessage(), e);
+		}finally {
+			this.catalogsLock.readLock().unlock();
+		}
+	}
+		
+	public TransactionReceipt ingest(Metadata metadata) throws CatalogServiceException {
+		if (this.restrictIngestPermissions) 
+			throw new CatalogServiceException("Ingest permissions are restricted for this CatalogService -- request denied");
+		try {	
+			boolean performUpdate = false;
+			TransactionId<?> catalogServiceTransactionId = this.getCatalogServiceTransactionId(metadata);
+			if (performUpdate = this.ingestMapper.hasCatalogServiceTransactionId(catalogServiceTransactionId)) 
+				LOG.log(Level.INFO, "TransactionId '" + catalogServiceTransactionId + "' is an existing TransactionId, switching to update mode");
+			List<CatalogReceipt> catalogReceipts = new Vector<CatalogReceipt>();
+			for (Catalog catalog : this.getFilteredCatalogList(metadata)) {			
+				if (catalog.isIngestable()) {
+					this.ingestMapperLock.writeLock().lock();
+					try {
+						// perform update
+						if (performUpdate) {
+							TransactionId<?> catalogTransactionId = this.ingestMapper.getCatalogTransactionId(catalogServiceTransactionId, catalog.getId());
+							if (catalogTransactionId != null) {
+								CatalogReceipt catalogReceipt = catalog.update(catalogTransactionId, metadata);
+								if (catalogReceipt != null) {
+									if (!catalogReceipt.getTransactionId().equals(catalogTransactionId)) {
+										this.ingestMapper.deleteTransactionIdMapping(catalogTransactionId, catalog.getId());
+										this.ingestMapper.storeTransactionIdMapping(catalogServiceTransactionId, this.transactionIdFactory, catalogReceipt, catalog.getTransactionIdFactory());
+									}
+									catalogReceipts.add(catalogReceipt);
+									LOG.log(Level.INFO, "Successfully updated metadata to catalog '" + catalog + "' for TransactionId '" + catalogServiceTransactionId + "'");
+								}else {
+									LOG.log(Level.SEVERE, "Update attempt to catalog '" + catalog + "' failed for TransactionId '" + catalogServiceTransactionId + "' -- update returned false");
+								}
+							}else {
+								LOG.log(Level.INFO, "Catalog '" + catalog + "' was not on ingest list for TransactionId '" + catalogServiceTransactionId + "' -- skipping");
+							}
+						// perform ingest	
+						}else {
+							LOG.log(Level.INFO, "Performing ingest for TransactionId '" + catalogServiceTransactionId + "' to catalog '" + catalog + "'");
+							CatalogReceipt catalogReceipt = catalog.ingest(metadata);
+							if (catalogReceipt != null) {
+								LOG.log(Level.INFO, "Successfully ingested metadata -- Indexing TransactionId information for ingest (CatalogService TransactionId = '" + catalogServiceTransactionId + "', Catalog TransactionId = '" + catalogReceipt.getTransactionId() + "', catalog = '" + catalogReceipt.getCatalogId() + "')");
+								this.ingestMapper.storeTransactionIdMapping(catalogServiceTransactionId, this.transactionIdFactory, catalogReceipt, catalog.getTransactionIdFactory());
+								catalogReceipts.add(catalogReceipt);
+							}else {
+								LOG.log(Level.WARNING, "Catalog '" + catalog + "' not interested in any Metadata for TransactionId '" + catalogServiceTransactionId + "'");
+							}
+						}
+					}catch (Exception e) {
+						LOG.log(Level.WARNING, "Failed to add metadata to catalog '" + catalog.getId() + "' : " + e.getMessage(), e);
+						if (this.oneCatalogFailsAllFail)
+							throw new CatalogServiceException("Failed to add metadata to catalog '" + catalog.getId() + "' : " + e.getMessage(), e);
+					}finally {
+						this.ingestMapperLock.writeLock().unlock();
+					}
+				}else {
+					LOG.log(Level.WARNING, "Ingest not permitted to catalog '" + catalog + "' -- skipping over catalog");
+				}
+			}
+			return (catalogReceipts.size() > 0) ? new TransactionReceipt(catalogServiceTransactionId, catalogReceipts) : null;
+		}catch (Exception e) {
+			throw new CatalogServiceException("Error occured during Metadata ingest attempt : " + e.getMessage(), e);
+		}
+	}
+	
+	/**
+	 * 
+	 * @param metadata
+	 * @throws CatalogServiceException
+	 */
+	public void delete(Metadata metadata) throws CatalogServiceException {
+		if (this.restrictIngestPermissions)
+			throw new CatalogServiceException("Delete permissions are restricted for this CatalogService -- request denied");
+		TransactionId<?> catalogServiceTransactionId = this.getCatalogServiceTransactionId(metadata, false);
+		if (catalogServiceTransactionId != null) {
+			for (Catalog catalog : this.getFilteredCatalogList(metadata)) {
+				if (catalog.isIngestable()) {
+					this.ingestMapperLock.writeLock().lock();
+					try {
+						TransactionId<?> catalogTransactionId = this.ingestMapper.getCatalogTransactionId(catalogServiceTransactionId, catalog.getId());
+						if (catalogTransactionId != null) {
+							if (this.doReduce(metadata)) {
+								LOG.log(Level.INFO, "Deleting metadata from TransactionId '" + catalogServiceTransactionId + "' for catalog '" + catalog + "'");
+								if (catalog.reduce(catalogTransactionId, metadata)) {
+									LOG.log(Level.INFO, "Successfully deleted metadata from catalog '" + catalog + "' for TransactionId [id = " + catalogServiceTransactionId + "]");
+								}else {
+									LOG.log(Level.INFO, "Failed to deleted metadata from catalog '" + catalog + "' for TransactionId [id = " + catalogServiceTransactionId + "] -- delete returned false");
+								}
+							}else {
+								LOG.log(Level.INFO, "Deleting all records of TransactionId from catalog '" + catalog + "'");
+								if (catalog.delete(catalogTransactionId)) {
+									this.ingestMapper.deleteTransactionIdMapping(catalogTransactionId, catalog.getId());
+									LOG.log(Level.INFO, "Successfully deleted metadata from catalog '" + catalog + "' for TransactionId [id = " + catalogServiceTransactionId + "]");
+								}else {
+									LOG.log(Level.INFO, "Failed to deleted metadata from catalog '" + catalog + "' for TransactionId [id = " + catalogServiceTransactionId + "] -- delete returned false");
+								}
+							}
+						}else {
+							LOG.log(Level.INFO, "Catalog '" + catalog + "' was not on delete list for TransactionId '" + catalogServiceTransactionId + "' -- skipping");
+						}
+					}catch (Exception e) {
+						LOG.log(Level.WARNING, "Error occured while deleting metadata for TransactionId [id = " + catalogServiceTransactionId + "] : " + e.getMessage(), e);
+						if (this.oneCatalogFailsAllFail)
+							throw new CatalogServiceException("Error occured while deleting metadata for TransactionId [id = " + catalogServiceTransactionId + "] : " + e.getMessage(), e);
+					}finally {
+						this.ingestMapperLock.writeLock().unlock();
+					}
+				}else {
+					LOG.log(Level.WARNING, "Deletion is not permitted to catalog '" + catalog + "' -- skipping over catalog");
+				}	
+			}
+		}else {
+			throw new CatalogServiceException("Must specify a TransactionId to delete");
+		}
+	}
+	
+	protected boolean doReduce(Metadata metadata) {
+		for (String key : metadata.getAllKeys())
+			if (!(key.equals(CATALOG_SERVICE_TRANSACTION_ID_MET_KEY) || key.equals(CATALOG_IDS_MET_KEY) || key.equals(CATALOG_TRANSACTION_ID_MET_KEY) || key.equals(CATALOG_ID_MET_KEY)))
+				return true;
+		return false;
+	}
+	
+	public List<String> getProperty(String key) throws CatalogServiceException {
+		List<String> vals = new Vector<String>();
+		for (Catalog catalog : this.getCurrentCatalogList()) {
+			try {
+				String val = catalog.getProperty(key);
+				if (val != null)
+					vals.add(val);
+			}catch (Exception e) {
+				if (this.oneCatalogFailsAllFail)
+					throw new CatalogServiceException("Failed to get catalog property '" + key + "' from catalog '" + catalog.getId() + "' : " + e.getMessage(), e);
+				else
+					LOG.log(Level.WARNING, "Failed to get catalog property '" + key + "' from catalog '" + catalog.getId() + "' : " + e.getMessage(), e);
+			}
+		}
+		return vals;
+	}
+
+	public Properties getCalalogProperties() throws CatalogServiceException {
+		Properties properties = new Properties();
+		for (Catalog catalog : this.getCurrentCatalogList()) {
+			try {
+				Properties catalogProperties = catalog.getProperties();
+				for (Object key : catalogProperties.keySet()) {
+					String value = properties.getProperty((String) key);
+					if (value != null)
+						value += "," + catalogProperties.getProperty((String) key);
+					else 
+						value = catalogProperties.getProperty((String) key);
+					properties.setProperty((String) key, value);
+				}
+			}catch (Exception e) {
+				if (this.oneCatalogFailsAllFail)
+					throw new CatalogServiceException("Failed to get catalog properties from catalog '" + catalog.getId() + "' : " + e.getMessage(), e);
+				else
+					LOG.log(Level.WARNING, "Failed to get catalog properties from catalog '" + catalog.getId() + "' : " + e.getMessage(), e);
+			}
+		}
+		return properties;
+	}
+	
+	public Properties getCalalogProperties(String catalogUrn) throws CatalogServiceException {
+		try {
+			Catalog catalog = this.getCatalog(catalogUrn);
+			if (catalog != null)
+				return catalog.getProperties();
+			else 
+				return null;
+		}catch (Exception e) {
+			throw new CatalogServiceException("Failed to get catalog properties from catalog '" + catalogUrn + "' : " + e.getMessage(), e);
+		}
+	}
+	
+	public Page getNextPage(Page page) throws CatalogServiceException {
+		QueryPager queryPager = new QueryPager(this._query(page.getQueryExpression(), page.getRestrictToCatalogIds()));
+		queryPager.setPageInfo(new PageInfo(page.getPageSize(), page.getPageNum() + 1));
+		return this.getPage(page.getQueryExpression(), page.getRestrictToCatalogIds(), queryPager);
+	}
+	
+	public Page getPage(PageInfo pageInfo, QueryExpression queryExpression) throws CatalogServiceException {
+		return this.getPage(pageInfo, queryExpression, this.getCurrentCatalogIds());
+	}
+	
+	public Page getPage(PageInfo pageInfo, QueryExpression queryExpression, Set<String> catalogIds) throws CatalogServiceException {
+		QueryPager queryPager = new QueryPager(this._query(queryExpression, catalogIds)); 
+		queryPager.setPageInfo(pageInfo);
+		return this.getPage(queryExpression, catalogIds, queryPager);	
+	}
+	
+	public QueryPager query(QueryExpression queryExpression) throws CatalogServiceException {
+		return this.query(queryExpression, this.getCurrentCatalogIds());
+	}
+
+	public List<TransactionalMetadata> getMetadata(Page page) throws CatalogServiceException {
+		return this.getMetadata(page.getReceipts());
+	}
+	
+	protected Page getPage(QueryExpression queryExpression, Set<String> restrictToCatalogIds, QueryPager queryPager) throws CatalogServiceException {
+		return new Page(new ProcessedPageInfo(queryPager.getPageSize(), queryPager.getPageNum(), queryPager.getNumOfHits()), queryExpression, restrictToCatalogIds, this.indexReceipts(queryPager.getCurrentPage()));
+	}
+	
+	public QueryPager query(QueryExpression queryExpression, Set<String> catalogIds) throws CatalogServiceException {
+		return new QueryPager(this.indexReceipts(this._query(queryExpression, catalogIds)));
+	}
+	
+	/**
+	 * 
+	 * @param queryExpression
+	 * @param indexPage
+	 * @return
+	 * @throws CatalogServiceException
+	 */
+	public List<TransactionReceipt> _query(QueryExpression queryExpression, Set<String> catalogIds) throws CatalogServiceException {
+		if (this.restrictQueryPermissions)
+			throw new CatalogServiceException("Query permissions are restricted for this CatalogService -- request denied");
+		try {
+			LOG.log(Level.INFO, "Recieved query '" + queryExpression + "'");
+			if (this.simplifyQueries) {
+				queryExpression = QueryUtils.simplifyQuery(queryExpression);
+				LOG.log(Level.INFO, "Simplified query to '" + queryExpression + "' -- routing query to catalogs");
+			}
+			QueryResult queryResult = this.queryRecur(queryExpression, catalogIds);
+			List<CatalogReceipt> catalogReceipts = new Vector<CatalogReceipt>();
+			if (queryResult.getCatalogReceipts() == null && queryResult.getInterestedCatalogs() != null) {
+				for (Catalog catalog : this.getCurrentCatalogList()) {
+					try {
+						if (queryResult.getInterestedCatalogs().contains(catalog.getId())) {
+							LOG.log(Level.INFO, "Restricting query to understood terms for Catalog '" + catalog + "'");
+							QueryExpression reducedExpression = this.reduceToUnderstoodExpressions(catalog, queryExpression);
+							LOG.log(Level.INFO, "Querying Catalog '" + catalog + "' with query '" + reducedExpression + "'");
+							catalogReceipts.addAll(catalog.query(reducedExpression));
+						}
+					}catch (Exception e) {
+						if (this.oneCatalogFailsAllFail)
+							throw new CatalogServiceException("Failed to query catalog '" + catalog.getId() + "' for query '" + queryExpression + "' : " + e.getMessage(), e);
+						else
+							LOG.log(Level.WARNING, "Failed to query catalog '" + catalog.getId() + "' for query '" + queryExpression + "' : " + e.getMessage(), e);
+					}	
+				}
+			}
+			List<TransactionReceipt> transactionReceipts = this.getPossiblyUnindexedTransactionReceipts(catalogReceipts);
+			LOG.log(Level.INFO, "Sorting Query Results . . . ");
+			Collections.sort(transactionReceipts, new Comparator<TransactionReceipt>() {
+				public int compare(TransactionReceipt o1,
+						TransactionReceipt o2) {
+					return o2.getTransactionDate().compareTo(o1.getTransactionDate());
+				}
+			});
+
+			LOG.log(Level.INFO, "Query returned " + transactionReceipts.size() + " results");
+			return transactionReceipts;
+		}catch (Exception e) {
+			e.printStackTrace();
+			throw new CatalogServiceException("Failed to get TransactionId to Metadata map for query '" + queryExpression + "' : " + e.getMessage(), e);
+		}
+	}
+	
+	protected List<TransactionReceipt> getPossiblyUnindexedTransactionReceipts(List<CatalogReceipt> catalogReceipts) throws CatalogServiceException {
+		try {
+			List<TransactionReceipt> returnList = new Vector<TransactionReceipt>();
+			HashMap<TransactionId<?>, List<CatalogReceipt>> existing = new HashMap<TransactionId<?>, List<CatalogReceipt>>();
+ 			for (CatalogReceipt catalogReceipt : catalogReceipts) {
+ 				TransactionId<?> catalogServiceTransactionId = this.getCatalogServiceTransactionId(catalogReceipt.getTransactionId(), catalogReceipt.getCatalogId());
+ 				if (catalogServiceTransactionId != null) {
+ 					List<CatalogReceipt> found = existing.get(catalogServiceTransactionId);
+ 					if (found == null) 
+ 						found = new Vector<CatalogReceipt>();
+ 					found.add(catalogReceipt);	
+ 					existing.put(catalogServiceTransactionId, found);
+ 				}else {
+ 					returnList.add(new TransactionReceipt(null, Collections.singletonList(catalogReceipt)));
+ 				}
+ 			}
+ 			for (TransactionId<?> transactionId : existing.keySet())
+ 				returnList.add(new TransactionReceipt(transactionId, existing.get(transactionId)));
+ 			return returnList;
+		}catch (Exception e) {
+			throw new CatalogServiceException("", e);
+		}
+	}
+	
+	protected List<TransactionReceipt> indexReceipts(List<TransactionReceipt> transactionReceipts) throws CatalogServiceException {
+		List<TransactionReceipt> indexedReceipts = new Vector<TransactionReceipt>();
+		for (TransactionReceipt transactionReceipt : transactionReceipts) {
+			try {
+//				for (CatalogReceipt catalogReceipt : transactionReceipt.getCatalogReceipts()) {
+					if (transactionReceipt.getTransactionId() == null)
+						transactionReceipt = new TransactionReceipt(this.getCatalogServiceTransactionId(transactionReceipt.getCatalogReceipts().get(0), true), transactionReceipt.getCatalogReceipts());
+//				}
+				indexedReceipts.add(transactionReceipt);
+			}catch(Exception e) {
+				throw new CatalogServiceException("", e);
+			}
+		}
+		return indexedReceipts;
+	}
+ 
+	public List<TransactionalMetadata> getNextPage(QueryPager queryPager) throws CatalogServiceException {
+		try {
+			return this.getMetadata(queryPager.getCurrentPage());
+		}catch (Exception e) {
+			throw new CatalogServiceException("Failed to get next page of Metadata : " + e.getMessage(), e);
+		}
+	}
+	
+	public List<TransactionalMetadata> getAllPages(QueryPager queryPager) throws CatalogServiceException {
+		try {
+			return this.getMetadata(queryPager.getTransactionReceipts());
+		}catch (Exception e) {
+			throw new CatalogServiceException("Failed to get all page of Metadata : " + e.getMessage(), e);
+		}	
+	}
+	
+	public List<TransactionalMetadata> getMetadataFromTransactionIdStrings(List<String> catalogServiceTransactionIdStrings) throws CatalogServiceException {
+		List<TransactionId<?>> catalogServiceTransactionIds = new Vector<TransactionId<?>>();
+		for (String catalogServiceTransactionIdString : catalogServiceTransactionIdStrings) 
+			catalogServiceTransactionIds.add(this.generateTransactionId(catalogServiceTransactionIdString));
+		return this.getMetadataFromTransactionIds(catalogServiceTransactionIds);
+	}
+	
+	public List<TransactionalMetadata> getMetadata(List<TransactionReceipt> transactionReceipts) throws CatalogServiceException {
+		LinkedHashSet<TransactionalMetadata> metadataSet = new LinkedHashSet<TransactionalMetadata>();
+		for (TransactionReceipt transactionReceipt : transactionReceipts) {
+			Metadata metadata = new Metadata();
+			Vector<CatalogReceipt> successfulCatalogReceipts = new Vector<CatalogReceipt>();
+			for (CatalogReceipt catalogReceipt : transactionReceipt.getCatalogReceipts()) {
+				try {
+					Catalog catalog = this.getCatalog(catalogReceipt.getCatalogId());
+					metadata.addMetadata(catalog.getMetadata(catalogReceipt.getTransactionId()));
+					successfulCatalogReceipts.add(catalogReceipt);
+				}catch (Exception e) {
+					if (this.oneCatalogFailsAllFail)
+						throw new CatalogServiceException("Failed to get metadata for transaction ids for catalog '" + catalogReceipt.getCatalogId() + "' : " + e.getMessage(), e);
+					else
+						LOG.log(Level.WARNING, "Failed to get metadata for transaction ids for catalog '" + catalogReceipt.getCatalogId() + "' : " + e.getMessage(), e);
+				}
+			}
+			if (metadata.getHashtable().keySet().size() > 0)
+				metadataSet.add(new TransactionalMetadata(new TransactionReceipt(transactionReceipt.getTransactionId(), successfulCatalogReceipts), metadata));
+		}
+		return new Vector<TransactionalMetadata>(metadataSet);
+	}
+	
+	public List<TransactionalMetadata> getMetadataFromTransactionIds(List<TransactionId<?>> catalogServiceTransactionIds) throws CatalogServiceException {
+		LinkedHashSet<TransactionalMetadata> metadataSet = new LinkedHashSet<TransactionalMetadata>();
+		for (TransactionId<?> catalogServiceTransactionId : catalogServiceTransactionIds) {
+			Metadata metadata = new Metadata();
+			Vector<CatalogReceipt> catalogReceipts = new Vector<CatalogReceipt>();
+			for (Catalog catalog : this.getCurrentCatalogList()) {
+				try {
+					CatalogReceipt catalogReceipt = this.ingestMapper.getCatalogReceipt(catalogServiceTransactionId, catalog.getId());
+					if (catalogReceipt != null) {
+						metadata.addMetadata(catalog.getMetadata(catalogReceipt.getTransactionId()).getHashtable());
+						catalogReceipts.add(catalogReceipt);
+					}
+				}catch (Exception e) {
+					if (this.oneCatalogFailsAllFail)
+						throw new CatalogServiceException("Failed to get metadata for transaction ids for catalog '" + catalog.getId() + "' : " + e.getMessage(), e);
+					else
+						LOG.log(Level.WARNING, "Failed to get metadata for transaction ids for catalog '" + catalog.getId() + "' : " + e.getMessage(), e);
+				}
+			}
+			if (metadata.getHashtable().keySet().size() > 0)
+				metadataSet.add(new TransactionalMetadata(new TransactionReceipt(catalogServiceTransactionId, catalogReceipts), metadata));
+		}
+		return new Vector<TransactionalMetadata>(metadataSet);
+	}
+	
+	public List<TransactionId<?>> getCatalogServiceTransactionIds(List<TransactionId<?>> catalogTransactionIds, String catalogUrn) throws CatalogServiceException {
+		LinkedHashSet<TransactionId<?>> catalogServiceTransactionIds = new LinkedHashSet<TransactionId<?>>();
+		for (TransactionId<?> catalogTransactionId : catalogTransactionIds) {
+			TransactionId<?> catalogServiceTransactionId = this.getCatalogServiceTransactionId(catalogTransactionId, catalogUrn);
+			catalogServiceTransactionIds.add(catalogServiceTransactionId);
+		}
+		return new Vector<TransactionId<?>>(catalogServiceTransactionIds); 
+	}
+	
+	public TransactionId<?> getCatalogServiceTransactionId(TransactionId<?> catalogTransactionId, String catalogUrn) throws CatalogServiceException {
+		this.ingestMapperLock.readLock().lock();
+		try {
+			return this.ingestMapper.getCatalogServiceTransactionId(catalogTransactionId, catalogUrn);
+		}catch (Exception e) {
+			throw new CatalogServiceException("", e);
+		}finally {
+			this.ingestMapperLock.readLock().unlock();
+		}
+	}
+	
+	public TransactionId<?> getCatalogServiceTransactionId(CatalogReceipt catalogReceipt, boolean generateNew) throws CatalogServiceException {
+		try {
+			TransactionId<?> catalogServiceTransactionId = this.getCatalogServiceTransactionId(catalogReceipt.getTransactionId(), catalogReceipt.getCatalogId());
+			if (catalogServiceTransactionId == null && generateNew) {
+				catalogServiceTransactionId = this.generateNewUniqueTransactionId();
+				LOG.log(Level.INFO, "CatalogServer mapping transaction: " + catalogServiceTransactionId + "," + catalogReceipt.getTransactionId() + "," + catalogReceipt.getCatalogId());
+				this.ingestMapperLock.writeLock().lock();
+				try {
+					this.ingestMapper.storeTransactionIdMapping(catalogServiceTransactionId, this.transactionIdFactory, catalogReceipt, this.getCatalog(catalogReceipt.getCatalogId()).getTransactionIdFactory());
+				}catch (Exception e) {
+					throw new CatalogServiceException("Failed to write TransactionId '" + catalogServiceTransactionId + "' : " + e.getMessage(), e);
+				}finally {
+					this.ingestMapperLock.writeLock().unlock();
+				}
+			}
+			return catalogServiceTransactionId;
+		}catch (Exception e) {
+			throw new CatalogServiceException("Failed to get CatalogServiceTransactionId : " + e.getMessage(), e);
+		}
+	}
+
+	protected TransactionId<?> generateNewUniqueTransactionId() {
+		try {
+			return this.transactionIdFactory.createNewTransactionId();
+		}catch (Exception e) {
+			LOG.log(Level.SEVERE, "Failed to generate a new TransactionId from factory '" + this.transactionIdFactory.getClass().getCanonicalName() + "' : " + e.getMessage(), e);
+			return null;
+		}
+	}
+	
+	protected TransactionId<?> generateTransactionId(String stringTransactionId) {
+		try {
+			return this.transactionIdFactory.createTransactionId(stringTransactionId);
+		}catch (Exception e) {
+			LOG.log(Level.SEVERE, "Failed to generate a new TransactionId from factory '" + this.transactionIdFactory.getClass().getCanonicalName() + "' for string value '" + stringTransactionId + ": " + e.getMessage(), e);
+			return null;
+		}
+	}
+	
+	// check if transaction id was specified by user, otherwise generate a new one
+	protected TransactionId<?> getCatalogServiceTransactionId(Metadata metadata) throws Exception {
+		return this.getCatalogServiceTransactionId(metadata, true);
+	}
+	
+	protected TransactionId<?> getCatalogServiceTransactionId(Metadata metadata, boolean generateNew) throws CatalogServiceException {
+		try {
+			if (metadata.getMetadata(CatalogServiceLocal.CATALOG_SERVICE_TRANSACTION_ID_MET_KEY) != null) {
+				return this.generateTransactionId(metadata.getMetadata(CatalogServiceLocal.CATALOG_SERVICE_TRANSACTION_ID_MET_KEY));
+			}else if (metadata.getMetadata(CatalogServiceLocal.CATALOG_TRANSACTION_ID_MET_KEY) != null && metadata.getMetadata(CatalogServiceLocal.CATALOG_ID_MET_KEY) != null) {
+				String catalogId = metadata.getMetadata(CatalogServiceLocal.CATALOG_ID_MET_KEY);
+				Catalog catalog = this.getCatalog(catalogId);
+				if (catalog != null) {
+					TransactionId<?> catalogTransactionId = catalog.getTransactionIdFromString(metadata.getMetadata(CatalogServiceLocal.CATALOG_TRANSACTION_ID_MET_KEY));
+					TransactionId<?> catalogServiceTransactionId = this.ingestMapper.getCatalogServiceTransactionId(catalogTransactionId, catalogId);
+					if (catalogServiceTransactionId == null)
+						throw new CatalogServiceException("CatalogService's Catalog '" + catalog.getId() + "' is not aware of TransactionId '" + catalogTransactionId + "'s");
+					return catalogServiceTransactionId;
+				}else {
+					throw new CatalogServiceException("This CatalogService has no Catalog with ID = '" + catalogId + "'");
+				}
+			}else if (generateNew) {
+				return this.generateNewUniqueTransactionId();
+			}else {
+				throw new CatalogServiceException("Metadata fields not present to determine a TransactionId");
+			}
+		}catch (Exception e) {
+			throw new CatalogServiceException("Failed determine TransactionId : " + e.getMessage(), e);
+		}
+	}
+	
+	protected Set<Catalog> getFilteredCatalogList(Metadata metadata) throws CatalogServiceException {
+		try {
+			if (metadata.containsKey(CATALOG_ID_MET_KEY)) {
+				Catalog catalog = this.getCatalog(metadata.getMetadata(CATALOG_ID_MET_KEY));
+				if (catalog == null)
+					throw new CatalogServiceException("Catalog '" + metadata.getMetadata(CATALOG_ID_MET_KEY) + "' is not managed by this CatalogService");
+				else
+					return Collections.singleton(catalog);
+			}else if (metadata.containsKey(CATALOG_IDS_MET_KEY)) {
+				HashSet<Catalog> filteredCatalogList = new HashSet<Catalog>();
+				for (Object catalogUrn : metadata.getAllMetadata(CATALOG_IDS_MET_KEY)) {
+					Catalog catalog = this.getCatalog((String) catalogUrn);
+					if (catalog == null)
+						throw new CatalogServiceException("Catalog '" + metadata.getMetadata(CATALOG_ID_MET_KEY) + "' is not managed by this CatalogService");
+					else
+						filteredCatalogList.add(catalog);
+				}
+				return filteredCatalogList;
+			}else {
+				return new HashSet<Catalog>(this.catalogs);
+			}
+		}catch (Exception e) {
+			throw new CatalogServiceException("Failed to get filtered catalog list : " + e.getMessage(), e);
+		}
+	}
+	
+	protected QueryResult queryRecur(QueryExpression queryExpression, Set<String> restrictToCatalogIds) throws CatalogServiceException, CatalogException {
+		// get QueryResults for sub queries
+		if (queryExpression instanceof QueryLogicalGroup) {
+			
+			// get children query results
+			List<QueryResult> childrenQueryResults = new Vector<QueryResult>();
+			for (QueryExpression subQueryExpression : ((QueryLogicalGroup) queryExpression).getExpressions()) 
+				childrenQueryResults.add(queryRecur(subQueryExpression, restrictToCatalogIds));
+			
+			// if (QueryLogicalGroup's operator is AND and is unbalanced or a child contains query results)
+			if ((((QueryLogicalGroup) queryExpression).getOperator().equals(QueryLogicalGroup.Operator.AND) && containsUnbalancedCatalogInterest(childrenQueryResults)) || containsTranactionReceipts(childrenQueryResults)) {
+				
+				for (int i = 0; i < childrenQueryResults.size(); i++) {
+					QueryResult childQueryResult = childrenQueryResults.get(i);
+					
+					// if childQueryResult has not been used, use it
+					if (childQueryResult.getCatalogReceipts() == null) { 
+						List<CatalogReceipt> catalogReceipts = new Vector<CatalogReceipt>();
+						for (Catalog catalog : this.getCurrentCatalogList()) {
+							try {
+								if (childQueryResult.getInterestedCatalogs().contains(catalog.getId())) 
+									catalogReceipts.addAll(catalog.query(this.reduceToUnderstoodExpressions(catalog, childQueryResult.getQueryExpression())));
+							}catch (Exception e) {
+								if (this.oneCatalogFailsAllFail)
+									throw new CatalogServiceException("Failed to query catalog '" + catalog.getId() + "' for query '" + queryExpression + "' : " + e.getMessage(), e);
+								else
+									LOG.log(Level.WARNING, "Failed to query catalog '" + catalog.getId() + "' for query '" + queryExpression + "' : " + e.getMessage(), e);
+							}
+						}
+						childQueryResult.setCatalogReceipts(catalogReceipts);
+					}
+					
+				}
+				
+				// get intersection of results
+	   			QueryResult queryResult = new QueryResult(queryExpression);
+	   			queryResult.setCatalogReceipts(this.getIntersection(childrenQueryResults));
+				return queryResult;
+			}else {
+				// get merge of results
+				QueryResult queryResult = new QueryResult(queryExpression);
+				HashSet<String> interestedCatalogs = new HashSet<String>();
+				for (QueryResult childQueryResult : childrenQueryResults)
+					interestedCatalogs.addAll(childQueryResult.getInterestedCatalogs());
+				queryResult.setInterestedCatalogs(interestedCatalogs);
+				return queryResult;
+			}
+		}else if (queryExpression instanceof WrapperQueryExpression) {
+
+			// check for catalogs interested in wrapper query expression
+			restrictToCatalogIds.retainAll(getInterestedCatalogs(queryExpression, restrictToCatalogIds));
+			
+			// check for catalogs interested in wrapped query expression
+			QueryResult wrapperExprQueryResult = null;
+			QueryExpression wrapperQE = ((WrapperQueryExpression) queryExpression).getQueryExpression();
+			if (wrapperQE instanceof QueryLogicalGroup) {
+				wrapperExprQueryResult = this.queryRecur((QueryLogicalGroup) wrapperQE, restrictToCatalogIds);
+			}else {
+				wrapperExprQueryResult = new QueryResult(wrapperQE);
+				wrapperExprQueryResult.interestedCatalogs = getInterestedCatalogs(wrapperQE, restrictToCatalogIds);
+				wrapperExprQueryResult.interestedCatalogs.retainAll(restrictToCatalogIds);
+			}				
+			return wrapperExprQueryResult;
+		}else {
+			// determine catalogs interested in this query expression
+			QueryResult queryResult = new QueryResult(queryExpression);
+			Set<String> interestedCatalogs = getInterestedCatalogs(queryExpression, restrictToCatalogIds);
+			interestedCatalogs.retainAll(restrictToCatalogIds);
+			queryResult.setInterestedCatalogs(interestedCatalogs);
+			return queryResult;
+		}
+	}
+	
+	protected List<CatalogReceipt> getIntersection(List<QueryResult> queryResults) {
+		List<CatalogReceipt> catalogReceipts = new Vector<CatalogReceipt>();
+		if (queryResults.size() > 0) {
+			catalogReceipts.addAll(queryResults.get(0).getCatalogReceipts());
+			for (int i = 1; i < queryResults.size(); i++) {
+				QueryResult qr = queryResults.get(i);
+TR:				for (CatalogReceipt catalogReceipt : qr.getCatalogReceipts()) {
+					for (CatalogReceipt compCatalogReceipt : catalogReceipts) {
+						if (catalogReceipt.getTransactionId().equals(compCatalogReceipt.getTransactionId()))
+							continue TR;
+					}
+					catalogReceipts.remove(catalogReceipt);
+				}
+			}
+		}
+		return catalogReceipts;
+	}
+
+	protected QueryExpression reduceToUnderstoodExpressions(Catalog catalog, QueryExpression queryExpression) throws CatalogDictionaryException, CatalogException {
+		if (queryExpression instanceof QueryLogicalGroup) {
+        	QueryLogicalGroup queryLogicalGroup = (QueryLogicalGroup) queryExpression;
+        	List<QueryExpression> restrictedExpressions = new Vector<QueryExpression>();
+        	for (QueryExpression qe : queryLogicalGroup.getExpressions()) {
+        		QueryExpression restrictedQE = this.reduceToUnderstoodExpressions(catalog, qe);
+        		if (restrictedQE != null)
+        			restrictedExpressions.add(restrictedQE);
+        	}
+        	if (restrictedExpressions.size() > 0) {
+        		if (restrictedExpressions.size() == 1) {
+        			return restrictedExpressions.get(0);
+        		}else {
+		        	QueryLogicalGroup restrictedQueryLogicalGroup = queryLogicalGroup.clone();
+		        	restrictedQueryLogicalGroup.setExpressions(restrictedExpressions);
+		        	return restrictedQueryLogicalGroup;
+        		}
+        	}else {
+        		return null;
+        	}
+		}else if (queryExpression instanceof WrapperQueryExpression) {
+			WrapperQueryExpression wrapperQueryExpresssion = (WrapperQueryExpression) queryExpression;
+        	if (catalog.isInterested(queryExpression)) {
+	        	QueryExpression qe = this.reduceToUnderstoodExpressions(catalog, wrapperQueryExpresssion.getQueryExpression());
+				if (qe != null) {
+					WrapperQueryExpression wqe = wrapperQueryExpresssion.clone();
+					wqe.setQueryExpression(qe);
+					return wqe;
+				}else if (wrapperQueryExpresssion.isValidWithNoSubExpression()){
+					WrapperQueryExpression wqe = wrapperQueryExpresssion.clone();
+					wqe.setQueryExpression(null);
+					return wqe;
+				}else {
+					return null;
+				}
+        	}else {
+        		return null;
+        	}
+        	
+        }else if (catalog.isInterested(queryExpression)) {
+        	return queryExpression;
+    	}else {
+    		return null;
+    	}
+	}
+	
+	protected boolean containsTranactionReceipts(List<QueryResult> queryResults) {
+		for (QueryResult queryResult : queryResults)
+			if (queryResult.getCatalogReceipts() != null)
+				return true;
+		return false;
+	}
+
+	protected boolean containsUnbalancedCatalogInterest(List<QueryResult> queryResults) {
+		if (queryResults.size() > 0) {
+			QueryResult firstQueryResult = queryResults.get(0);
+			for (int i = 1; i < queryResults.size(); i++) {
+				QueryResult queryResult = queryResults.get(i);
+				if (!(queryResult.interestedCatalogs.containsAll(firstQueryResult.interestedCatalogs) && firstQueryResult.interestedCatalogs.containsAll(queryResult.interestedCatalogs)))
+					return true;
+			}
+			return false;
+		}else {
+			return false;
+		}
+	}
+
+	protected HashSet<String> getInterestedCatalogs(QueryExpression queryExpression, Set<String> restrictToCatalogIds) throws CatalogException, CatalogServiceException {
+		HashSet<String> interestedCatalogs = new HashSet<String>();
+		for (Catalog catalog : this.getCurrentCatalogList()) {
+			try {
+				if (restrictToCatalogIds.contains(catalog.getId())) {
+					if (catalog.isInterested(queryExpression))
+						interestedCatalogs.add(catalog.getId());
+				}
+			}catch (Exception e) {
+				if (this.oneCatalogFailsAllFail)
+					throw new CatalogException("Failed to determine if Catalog '" + catalog.getId() + "' is interested in query expression '" + queryExpression + "' : " + e.getMessage(), e);
+				else
+					LOG.log(Level.WARNING, "Failed to determine if Catalog '" + catalog.getId() + "' is interested in query expression '" + queryExpression + "' : " + e.getMessage(), e);
+			}
+		}
+		return interestedCatalogs;
+	}
+
+	protected class QueryResult {
+		
+		private QueryExpression queryExpression;
+		private List<CatalogReceipt> catalogReceipts;
+		private Set<String> interestedCatalogs;
+		
+		public QueryResult(QueryExpression queryExpression) {
+			this.queryExpression = queryExpression;
+		}
+
+		public QueryExpression getQueryExpression() {
+			return queryExpression;
+		}
+
+		public void setQueryExpression(QueryExpression queryExpression) {
+			this.queryExpression = queryExpression;
+		}
+
+		public List<CatalogReceipt> getCatalogReceipts() {
+			return catalogReceipts;
+		}
+
+		public void setCatalogReceipts(
+				List<CatalogReceipt> catalogReceipts) {
+			this.catalogReceipts = catalogReceipts;
+		}
+
+		public Set<String> getInterestedCatalogs() {
+			return interestedCatalogs;
+		}
+
+		public void setInterestedCatalogs(Set<String> interestedCatalogs) {
+			this.interestedCatalogs = interestedCatalogs;
+		}
+	
+	}
+	
+	protected class QueryResultGroup {
+		HashSet<TransactionReceipt> transactionReceipts;
+		String id;
+		
+		public QueryResultGroup(String id) {
+			this.id = id;
+			transactionReceipts = new HashSet<TransactionReceipt>();
+		}
+		
+		public HashSet<TransactionReceipt> getResults() {
+			return this.transactionReceipts;
+		}
+		
+		public void addTransactionReceipt(TransactionReceipt transactionReceipt) {
+			this.transactionReceipts.add(transactionReceipt);
+		}
+	}
+		
+}

Added: incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/system/impl/CatalogServiceLocalFactory.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/system/impl/CatalogServiceLocalFactory.java?rev=1002752&view=auto
==============================================================================
--- incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/system/impl/CatalogServiceLocalFactory.java (added)
+++ incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/system/impl/CatalogServiceLocalFactory.java Wed Sep 29 17:19:09 2010
@@ -0,0 +1,107 @@
+/*
+ * 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.oodt.cas.catalog.system.impl;
+
+//JDK imports
+import java.io.File;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+//OODT imports
+import org.apache.oodt.cas.catalog.mapping.IngestMapperFactory;
+import org.apache.oodt.cas.catalog.repository.CatalogRepositoryFactory;
+import org.apache.oodt.cas.catalog.struct.TransactionIdFactory;
+import org.apache.oodt.cas.catalog.system.CatalogServiceFactory;
+
+//Spring imports
+import org.springframework.beans.factory.annotation.Required;
+
+//OODT imports
+
+/**
+ * @author bfoster
+ * @version $Revision$
+ *
+ * <p>
+ * A Factory class for CatalogServiceLocal
+ * <p>
+ */
+public class CatalogServiceLocalFactory implements CatalogServiceFactory {
+
+	private static Logger LOG = Logger.getLogger(CatalogServiceLocalFactory.class.getName());
+	
+	protected CatalogRepositoryFactory catalogRepositoryFactory = null;
+	protected IngestMapperFactory ingestMapperFactory  = null;
+	protected boolean restrictQueryPermissions = false;
+	protected boolean restrictIngestPermissions = false;
+	protected TransactionIdFactory transactionIdFactory = null;
+	protected String pluginStorageDir = null;
+	protected boolean oneCatalogFailsAllFail = false;
+	protected boolean simplifyQueries = false;
+	
+	public CatalogServiceLocalFactory() {} 
+	
+	public CatalogServiceLocal createCatalogService() {
+		try {
+			return new CatalogServiceLocal(this.catalogRepositoryFactory.createRepository(), this.ingestMapperFactory.createMapper(), new File(this.pluginStorageDir), this.transactionIdFactory, this.restrictQueryPermissions, this.restrictIngestPermissions, this.oneCatalogFailsAllFail, this.simplifyQueries);
+		}catch (Exception e) {
+			LOG.log(Level.SEVERE, "Failed to create CatalogServiceLocal : " + e.getMessage(), e);
+			return null;
+		}
+	}
+
+	@Required
+	public void setCatalogRepositoryFactory(CatalogRepositoryFactory catalogRepositoryFactory) {
+		this.catalogRepositoryFactory = catalogRepositoryFactory;
+	}
+
+	@Required
+	public void setIngestMapperFactory(IngestMapperFactory ingestMapperFactory) {
+		this.ingestMapperFactory = ingestMapperFactory;
+	}
+
+	@Required
+	public void setRestrictQueryPermissions(boolean restrictQueryPermissions) {
+		this.restrictQueryPermissions = restrictQueryPermissions;
+	}
+
+	@Required
+	public void setRestrictIngestPermissions(boolean restrictIngestPermissions) {
+		this.restrictIngestPermissions = restrictIngestPermissions;
+	}
+
+	@Required
+	public void setTransactionIdFactory(String transactionIdFactory) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+		this.transactionIdFactory = (TransactionIdFactory) Class.forName(transactionIdFactory).newInstance();
+	}
+	
+	@Required
+	public void setPluginStorageDir(String pluginStorageDir) {
+		this.pluginStorageDir = pluginStorageDir;
+	}
+	
+	@Required
+	public void setOneCatalogFailsAllFail(boolean oneCatalogFailsAllFail) {
+		this.oneCatalogFailsAllFail = oneCatalogFailsAllFail;
+	}
+
+	@Required
+	public void setSimplifyQueries(boolean simplifyQueries) {
+		this.simplifyQueries = simplifyQueries;
+	}
+	
+}

Added: incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/term/Bucket.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/term/Bucket.java?rev=1002752&view=auto
==============================================================================
--- incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/term/Bucket.java (added)
+++ incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/term/Bucket.java Wed Sep 29 17:19:09 2010
@@ -0,0 +1,47 @@
+/*
+ * 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.oodt.cas.catalog.term;
+
+/**
+ * @author bfoster
+ * @version $Revision$
+ *
+ * <p>
+ * A Bucket represents an ingestable or queriable group
+ * <p>
+ */
+public class Bucket {
+
+	private String name;
+	
+	public Bucket() {
+		this.name = "Default";
+	}
+	
+	public Bucket(String name) {
+		this.name = name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getName() {
+		return this.name;
+	}
+
+}

Added: incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/term/Term.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/term/Term.java?rev=1002752&view=auto
==============================================================================
--- incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/term/Term.java (added)
+++ incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/term/Term.java Wed Sep 29 17:19:09 2010
@@ -0,0 +1,161 @@
+/*
+ * 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.oodt.cas.catalog.term;
+
+//JDK imports
+import java.util.Collections;
+import java.util.List;
+import java.util.Vector;
+
+/**
+ * @author bfoster
+ * @version $Revision$
+ *
+ * <p>
+ * A ingestable or queriable item
+ * <p>
+ */
+public class Term implements Cloneable {
+
+	protected String name;
+	protected List<String> values;
+	protected Type type;
+	public enum Type { 
+		xml_boolean,
+		xml_base64Binary,
+		xml_hexBinary,
+		xml_anyURI,
+		xml_language,
+		xml_normalizedString,
+		xml_string,
+		xml_token,
+		xml_byte,
+		xml_decimal,
+		xml_double,
+		xml_float,
+		xml_int,
+		xml_integer,
+		xml_long,
+		xml_negativeInteger,
+		xml_nonNegativeInteger,
+		xml_nonPositiveInteger,
+		xml_positiveInteger,
+		xml_short,
+		xml_unsignedByte,
+		xml_unsignedInt,
+		xml_unsignedLong,
+		xml_unsignedShort,
+		xml_date,
+		xml_dateTime,
+		xml_duration,
+		xml_gDay,
+		xml_gMonth,
+		xml_gMonthDay,
+		xml_gYear,
+		xml_gYearMonth,
+		xml_time,
+		xml_Name,
+		xml_NCName,
+		xml_NOTATION,
+		xml_QName,
+		xml_ENTITY,
+		xml_ENTITIES,
+		xml_ID,
+		xml_IDREF,
+		xml_IDREFS,
+		xml_NMTOKEN,
+		xml_NMTOKENS,
+		xml_anyType,
+		xml_anySimpleType
+	};
+	
+	public Term() {
+		this.type = Type.xml_string;
+		this.values = Collections.emptyList();
+	}
+	
+	public Term(String name) {
+		this();
+		this.name = name;
+	}
+	
+	public Term(String name, List<String> values) {
+		this(name);
+		this.setValues(values);
+	}
+	
+	public Term(String name, List<String> values, Type type) {
+		this(name, values);
+		if (type != null)
+			this.type = type;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public List<String> getValues() {
+		return values;
+	}
+
+	public void setValues(List<String> values) {
+		this.values = new Vector<String>(values);
+	}
+	
+	public String getFirstValue() {
+		String firstValue = null;
+		if (this.values.size() > 0)
+			firstValue = this.values.get(0);
+		return firstValue; 
+	}
+
+	public Type getType() {
+		return type;
+	}
+
+	public void setType(Type type) {
+		this.type = type;
+	}
+	
+	@Override
+	public int hashCode() {
+		return this.name.hashCode();
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (obj instanceof Term) {
+			Term compareToTerm = (Term) obj;
+			return (this.name.equals(compareToTerm.name)
+					&& this.type.equals(compareToTerm.type)
+					&& this.values.containsAll(compareToTerm.values) && compareToTerm.values
+					.containsAll(this.values));
+		}else {
+			return false;
+		}
+	}
+	
+	@Override
+	public Term clone() {
+		return new Term(this.name, this.values, this.type);
+	}
+
+}

Added: incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/term/TermBucket.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/term/TermBucket.java?rev=1002752&view=auto
==============================================================================
--- incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/term/TermBucket.java (added)
+++ incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/term/TermBucket.java Wed Sep 29 17:19:09 2010
@@ -0,0 +1,101 @@
+/*
+ * 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.oodt.cas.catalog.term;
+
+//JDK imports
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+/**
+ * @author bfoster
+ * @version $Revision$
+ *
+ * <p>
+ * A Bucket which has Terms attached to it
+ * <p>
+ */
+public class TermBucket extends Bucket {
+
+	private HashMap<String, Term> terms;
+	
+	public TermBucket() {
+		super();
+		this.terms = new HashMap<String, Term>();
+	}
+	
+	public TermBucket(String name) {
+		super(name);
+		this.terms = new HashMap<String, Term>();
+	}
+	
+	public TermBucket(String name, Set<Term> terms) {
+		this(name);
+		this.setTerms(terms);
+	}
+	
+	public void setTerms(Set<Term> terms) {
+		if (terms != null) {
+			this.terms = new HashMap<String, Term>();
+			for (Term term : terms)
+				this.terms.put(term.name, term);
+		}
+	}
+	
+	public void addTerms(Set<Term> terms) {
+		this.addTerms(terms, false);
+	}
+	
+	public void addTerms(Set<Term> terms, boolean replace) {
+		if (replace) {
+			for (Term term : terms)
+				this.terms.put(term.name, term);
+		}else {
+			for (Term term : terms) {
+				Term found = this.terms.get(term.name);
+				if (found != null) {
+					List<String> newTermValues = new Vector<String>();
+					newTermValues.addAll(found.getValues());
+					newTermValues.addAll(term.getValues());
+					found.setValues(newTermValues);
+				}else {
+					this.terms.put(term.name, term);
+				}
+			}
+		}
+	}
+	
+	public void addTerm(Term term) {
+		this.addTerms(Collections.singleton(term));
+	}
+	
+	public void addTerm(Term term, boolean replace) {
+		this.addTerms(Collections.singleton(term), replace);
+	}
+	
+	public Set<Term> getTerms() {
+		return Collections.unmodifiableSet(new HashSet<Term>(this.terms.values()));
+	}
+	
+	public Term getTermByName(String termName) {
+		return this.terms.get(termName);
+	}
+	
+}

Added: incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/CasPropertyPlaceholderConfigurer.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/CasPropertyPlaceholderConfigurer.java?rev=1002752&view=auto
==============================================================================
--- incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/CasPropertyPlaceholderConfigurer.java (added)
+++ incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/CasPropertyPlaceholderConfigurer.java Wed Sep 29 17:19:09 2010
@@ -0,0 +1,55 @@
+/*
+ * 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.oodt.cas.catalog.util;
+
+//OODT imports
+import org.apache.oodt.cas.metadata.util.PathUtils;
+
+//Spring imports
+import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
+
+/**
+ * 
+ * @author bfoster
+ * @version $Revision$
+ *
+ * <p>Describe your class here</p>.
+ */
+public class CasPropertyPlaceholderConfigurer extends
+        PropertyPlaceholderConfigurer {
+
+    @Override
+    protected String convertPropertyValue(String value) {
+        try {
+        	String defaultValue = null;
+        	String[] splitValue = value.split(";");
+        	if (splitValue.length == 2) {
+        		value = splitValue[0];
+        		defaultValue = splitValue[1];
+        	}
+            String result = PathUtils.doDynamicReplacement(value);
+            if (result.equals("null"))
+            	return defaultValue;
+            else
+            	return result;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return value;
+        }
+    }
+
+}

Added: incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/PluginClassLoader.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/PluginClassLoader.java?rev=1002752&view=auto
==============================================================================
--- incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/PluginClassLoader.java (added)
+++ incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/PluginClassLoader.java Wed Sep 29 17:19:09 2010
@@ -0,0 +1,95 @@
+/*
+ * 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.oodt.cas.catalog.util;
+
+//JDK imports
+import java.io.File;
+import java.io.FileFilter;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.List;
+import java.util.Vector;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+//OODT imports
+import org.apache.oodt.cas.metadata.util.PathUtils;
+
+/**
+ * 
+ * @author bfoster
+ * @version $Revision$
+ *
+ * <p>Java ClassLoader for loading plugin classes in Catalogs and QueryExpressions</p>.
+ */
+public class PluginClassLoader extends URLClassLoader {
+
+	private static final Logger LOG = Logger.getLogger(PluginClassLoader.class.getName());
+	
+	public PluginClassLoader() {
+		super(getPluginURLs());
+	}
+	
+	public PluginClassLoader(ClassLoader parent) {
+		super(new URL[0], parent);
+	}
+
+	protected void addURL(PluginURL pluginURL) {
+		super.addURL(pluginURL.getURL());
+	}
+	
+	protected void addURLs(List<URL> urls) {
+		for (URL url : urls)
+			this.addURL(url);
+	}
+	
+	public static URL[] getPluginURLs() {
+		List<URL> urls = new Vector<URL>();
+		try {
+			String pluginDirs = System.getProperty("org.apache.oodt.cas.catalog.plugin.dirs");
+			if (pluginDirs != null) {
+				for (String pluginDir : PathUtils.doDynamicReplacement(pluginDirs).split(",")) {
+					File[] jarFiles = new File(pluginDir).listFiles(new FileFilter() {
+						public boolean accept(File pathname) {
+							return pathname.getName().endsWith(".jar");
+						}					
+					});
+					for (File jarFile : jarFiles) {
+						try {
+							urls.add(jarFile.toURL());
+						}catch (Exception e) {
+							LOG.log(Level.SEVERE, "Failed to load jar file '" + jarFile + "' : " + e.getMessage(), e);
+						}
+					
+					}
+				}
+			}
+		}catch (Exception e) {}
+		return urls.toArray(new URL[urls.size()]);
+	}
+	
+	public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+		try {
+			Class<?> clazz = this.findLoadedClass(name);
+			if (clazz == null)
+				clazz = this.findClass(name);
+			return clazz;
+		}catch (Exception e) {}
+		return super.loadClass(name, resolve);
+	}
+
+}

Added: incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/PluginURL.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/PluginURL.java?rev=1002752&view=auto
==============================================================================
--- incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/PluginURL.java (added)
+++ incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/PluginURL.java Wed Sep 29 17:19:09 2010
@@ -0,0 +1,47 @@
+/*
+ * 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.oodt.cas.catalog.util;
+
+//JDK imports
+import java.net.URL;
+
+/**
+ * 
+ * @author bfoster
+ * @version $Revision$
+ *
+ * <p>Plugin URL for transfering Jars to server side</p>.
+ */
+public class PluginURL{
+
+	protected String catalogId;
+	protected URL url;
+	
+	public PluginURL(String catalogId, URL url) {
+		this.catalogId = catalogId;
+		this.url = url;
+	}
+	
+	public String getCatalogId() {
+		return this.catalogId;
+	}
+	
+	public URL getURL() {
+		return this.url;
+	}
+	
+}

Added: incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/QueryUtils.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/QueryUtils.java?rev=1002752&view=auto
==============================================================================
--- incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/QueryUtils.java (added)
+++ incubator/oodt/trunk/catalog/src/main/java/org/apache/oodt/cas/catalog/util/QueryUtils.java Wed Sep 29 17:19:09 2010
@@ -0,0 +1,147 @@
+/*
+ * 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.oodt.cas.catalog.util;
+
+//JDK imports
+import java.util.List;
+import java.util.Vector;
+
+//OODT imports
+import org.apache.oodt.cas.catalog.metadata.TransactionalMetadata;
+import org.apache.oodt.cas.catalog.query.QueryExpression;
+import org.apache.oodt.cas.catalog.query.QueryLogicalGroup;
+import org.apache.oodt.cas.catalog.query.WrapperQueryExpression;
+import org.apache.oodt.cas.catalog.query.filter.QueryFilter;
+import org.apache.oodt.cas.catalog.query.parser.ParseException;
+import org.apache.oodt.cas.catalog.query.parser.QueryParser;
+import org.apache.oodt.cas.catalog.query.parser.TokenMgrError;
+
+//OODT imports
+
+/**
+ * @author bfoster
+ * @version $Revision$
+ *
+ * <p>
+ * Utilities for helping filter query results
+ * <p>
+ */
+public class QueryUtils {
+
+	public static List<TransactionalMetadata> filterMetadata(QueryFilter<?> queryFilter, List<TransactionalMetadata> metadataList) {
+		return queryFilter.filterMetadataList(metadataList);
+	}
+	
+	public static List<TransactionalMetadata> sort(List<TransactionalMetadata> metadataList, String sortByMetadataKey) {
+		return null;
+	}
+	
+	public static QueryExpression simplifyQuery(QueryExpression queryExpression) {
+		return _simplifyQuery(queryExpression.clone());
+	}
+	
+	/**
+	 * Might later be factored out into a Query Normalizer Interface . . . this method currently compacts AND(s).
+	 * @param queryExpression Query to be simplified
+	 * @return simplified query
+	 */
+	private static QueryExpression _simplifyQuery(QueryExpression queryExpression) {
+		if (queryExpression instanceof QueryLogicalGroup) {
+			QueryLogicalGroup.Operator operator = ((QueryLogicalGroup) queryExpression).getOperator();
+			boolean changed;
+			do {
+				changed = false;
+				Vector<QueryExpression> children = new Vector<QueryExpression>();
+				for (QueryExpression qe : ((QueryLogicalGroup) queryExpression).getExpressions()) {
+					if (qe instanceof QueryLogicalGroup && ((QueryLogicalGroup) qe).getOperator().equals(operator)) {
+						children.addAll(((QueryLogicalGroup) qe).getExpressions());
+						changed = true;
+					}else {
+						children.add(qe);
+					}
+				}
+				((QueryLogicalGroup) queryExpression).setExpressions(children);
+			}while(changed);
+		}else if (queryExpression instanceof WrapperQueryExpression) {
+			((WrapperQueryExpression) queryExpression).setQueryExpression(((WrapperQueryExpression) queryExpression).getQueryExpression());
+		}
+		return queryExpression;
+	}
+	
+	public static void main(String[] args) throws ParseException, TokenMgrError {
+		QueryExpression qe = QueryParser.parseQueryExpression("{bucketNames = 'joe,tim' ; Name == 'Tim,Joe' AND City == 'Upland' AND State == 'CA'}");
+		System.out.println(qe.toString());
+		System.out.println(simplifyQuery(qe).toString());
+		System.out.println("");
+		qe = QueryParser.parseQueryExpression("Name == 'Tim,Joe' AND (City == 'Upland' AND State == 'CA')");
+		System.out.println(qe.toString());
+		System.out.println(simplifyQuery(qe).toString());
+	}
+	
+//	public static QueryExpression convertAndsToOrs(QueryExpression queryExpression) {
+//		if (queryExpression instanceof QueryLogicalGroup) {
+//			if (((QueryLogicalGroup) queryExpression).getOperator().equals(QueryLogicalGroup.Operator.AND)) {
+//				QueryLogicalGroup convertedQueryExpression = new QueryLogicalGroup();
+//				convertedQueryExpression.setOperator(QueryLogicalGroup.Operator.OR);
+//				for (QueryExpression subQueryExpression : ((QueryLogicalGroup) queryExpression).getExpressions())
+//					convertedQueryExpression.addExpression(new NotQueryExpression(convertAndsToOrs(subQueryExpression)));
+//				return new NotQueryExpression(convertedQueryExpression);
+//			}else {
+//				QueryLogicalGroup convertedQueryExpression = new QueryLogicalGroup();
+//				convertedQueryExpression.setOperator(QueryLogicalGroup.Operator.OR);
+//				for (QueryExpression subQueryExpression : ((QueryLogicalGroup) queryExpression).getExpressions()) 
+//					convertedQueryExpression.addExpression(convertAndsToOrs(subQueryExpression));
+//				return convertedQueryExpression;
+//			}
+//		}else if (queryExpression instanceof NotQueryExpression) {
+//			return new NotQueryExpression(convertAndsToOrs(((NotQueryExpression) queryExpression).getQueryExpression()));
+//		}else {
+//			return queryExpression;
+//		}
+//	}
+//	
+//	public static QueryExpression reduceNots(QueryExpression queryExpression) {
+//		if (queryExpression instanceof NotQueryExpression) {
+//			NotQueryExpression notQueryExpression = (NotQueryExpression) queryExpression;
+//			if (notQueryExpression.getQueryExpression() instanceof QueryLogicalGroup && ((QueryLogicalGroup) notQueryExpression.getQueryExpression()).getOperator().equals(QueryLogicalGroup.Operator.OR)) {
+//				QueryLogicalGroup queryLogicalGroup = (QueryLogicalGroup) notQueryExpression.getQueryExpression();
+//				QueryLogicalGroup newQueryLogicalGroup = new QueryLogicalGroup();
+//				newQueryLogicalGroup.setOperator(QueryLogicalGroup.Operator.AND);
+//				for (QueryExpression subQueryExpression : queryLogicalGroup.getExpressions()) {
+//					if (subQueryExpression instanceof NotQueryExpression) {
+//						newQueryLogicalGroup.addExpression(reduceNots(((NotQueryExpression) subQueryExpression).getQueryExpression()));
+//					}else {
+//						newQueryLogicalGroup.addExpression(new NotQueryExpression(reduceNots(subQueryExpression)));
+//					}
+//				}
+//				return newQueryLogicalGroup;
+//			}else {
+//				return new NotQueryExpression(reduceNots(notQueryExpression.getQueryExpression()));
+//			}
+//		}else if (queryExpression instanceof QueryLogicalGroup){
+//			QueryLogicalGroup queryLogicalGroup = (QueryLogicalGroup) queryExpression;
+//			QueryLogicalGroup newQueryLogicalGroup = new QueryLogicalGroup();
+//			newQueryLogicalGroup.setOperator(queryLogicalGroup.getOperator());
+//			for (QueryExpression subQueryExpression : queryLogicalGroup.getExpressions())
+//				newQueryLogicalGroup.addExpression(reduceNots(subQueryExpression));
+//			return newQueryLogicalGroup;
+//		}else {
+//			return queryExpression;
+//		}
+//	}
+	
+}



Mime
View raw message