From 5a2aeb3ab59f286a6d2a5d8b7d62f4b17132b2b7 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Wed, 30 Aug 2006 02:24:36 +0000 Subject: Add core repository implementations --- .../amazon/carbonado/repo/logging/CommonsLog.java | 44 ++++++ .../com/amazon/carbonado/repo/logging/Log.java | 30 +++++ .../repo/logging/LogAccessCapability.java | 30 +++++ .../carbonado/repo/logging/LoggingQuery.java | 98 ++++++++++++++ .../carbonado/repo/logging/LoggingRepository.java | 114 ++++++++++++++++ .../repo/logging/LoggingRepositoryBuilder.java | 150 +++++++++++++++++++++ .../carbonado/repo/logging/LoggingStorage.java | 138 +++++++++++++++++++ .../carbonado/repo/logging/LoggingTransaction.java | 69 ++++++++++ .../carbonado/repo/logging/package-info.java | 25 ++++ 9 files changed, 698 insertions(+) create mode 100644 src/main/java/com/amazon/carbonado/repo/logging/CommonsLog.java create mode 100644 src/main/java/com/amazon/carbonado/repo/logging/Log.java create mode 100644 src/main/java/com/amazon/carbonado/repo/logging/LogAccessCapability.java create mode 100644 src/main/java/com/amazon/carbonado/repo/logging/LoggingQuery.java create mode 100644 src/main/java/com/amazon/carbonado/repo/logging/LoggingRepository.java create mode 100644 src/main/java/com/amazon/carbonado/repo/logging/LoggingRepositoryBuilder.java create mode 100644 src/main/java/com/amazon/carbonado/repo/logging/LoggingStorage.java create mode 100644 src/main/java/com/amazon/carbonado/repo/logging/LoggingTransaction.java create mode 100644 src/main/java/com/amazon/carbonado/repo/logging/package-info.java (limited to 'src/main/java/com/amazon/carbonado/repo/logging') diff --git a/src/main/java/com/amazon/carbonado/repo/logging/CommonsLog.java b/src/main/java/com/amazon/carbonado/repo/logging/CommonsLog.java new file mode 100644 index 0000000..f3fca4b --- /dev/null +++ b/src/main/java/com/amazon/carbonado/repo/logging/CommonsLog.java @@ -0,0 +1,44 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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 com.amazon.carbonado.repo.logging; + +/** + * Log implementation that uses Jakarta Commons Logging at debug level. + * + * @author Brian S O'Neill + */ +public class CommonsLog implements Log { + private final org.apache.commons.logging.Log mLog; + + public CommonsLog(org.apache.commons.logging.Log log) { + mLog = log; + } + + public CommonsLog(Class clazz) { + mLog = org.apache.commons.logging.LogFactory.getLog(clazz); + } + + public boolean isEnabled() { + return mLog.isDebugEnabled(); + } + + public void write(String message) { + mLog.debug(message); + } +} diff --git a/src/main/java/com/amazon/carbonado/repo/logging/Log.java b/src/main/java/com/amazon/carbonado/repo/logging/Log.java new file mode 100644 index 0000000..d5ac74e --- /dev/null +++ b/src/main/java/com/amazon/carbonado/repo/logging/Log.java @@ -0,0 +1,30 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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 com.amazon.carbonado.repo.logging; + +/** + * Very simple Log interface. + * + * @author Brian S O'Neill + */ +public interface Log { + boolean isEnabled(); + + void write(String message); +} diff --git a/src/main/java/com/amazon/carbonado/repo/logging/LogAccessCapability.java b/src/main/java/com/amazon/carbonado/repo/logging/LogAccessCapability.java new file mode 100644 index 0000000..fe3a59a --- /dev/null +++ b/src/main/java/com/amazon/carbonado/repo/logging/LogAccessCapability.java @@ -0,0 +1,30 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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 com.amazon.carbonado.repo.logging; + +import com.amazon.carbonado.capability.Capability; + +/** + * Provides access to the Log. + * + * @author Brian S O'Neill + */ +public interface LogAccessCapability extends Capability { + Log getLog(); +} diff --git a/src/main/java/com/amazon/carbonado/repo/logging/LoggingQuery.java b/src/main/java/com/amazon/carbonado/repo/logging/LoggingQuery.java new file mode 100644 index 0000000..2535c74 --- /dev/null +++ b/src/main/java/com/amazon/carbonado/repo/logging/LoggingQuery.java @@ -0,0 +1,98 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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 com.amazon.carbonado.repo.logging; + +import com.amazon.carbonado.Cursor; +import com.amazon.carbonado.FetchException; +import com.amazon.carbonado.PersistException; +import com.amazon.carbonado.Query; +import com.amazon.carbonado.Storable; +import com.amazon.carbonado.Storage; + +import com.amazon.carbonado.spi.WrappedQuery; + +/** + * + * + * @author Brian S O'Neill + */ +class LoggingQuery extends WrappedQuery { + private final LoggingStorage mStorage; + + LoggingQuery(LoggingStorage storage, Query query) { + super(query); + mStorage = storage; + } + + public Cursor fetch() throws FetchException { + Log log = mStorage.mRepo.getLog(); + if (log.isEnabled()) { + log.write("Query.fetch() on " + this); + } + return super.fetch(); + } + + public S loadOne() throws FetchException { + Log log = mStorage.mRepo.getLog(); + if (log.isEnabled()) { + log.write("Query.loadOne() on " + this); + } + return super.loadOne(); + } + + public S tryLoadOne() throws FetchException { + Log log = mStorage.mRepo.getLog(); + if (log.isEnabled()) { + log.write("Query.tryLoadOne() on " + this); + } + return super.tryLoadOne(); + } + + public void deleteOne() throws PersistException { + Log log = mStorage.mRepo.getLog(); + if (log.isEnabled()) { + log.write("Query.deleteOne() on " + this); + } + super.deleteOne(); + } + + public boolean tryDeleteOne() throws PersistException { + Log log = mStorage.mRepo.getLog(); + if (log.isEnabled()) { + log.write("Query.tryDeleteOne() on " + this); + } + return super.tryDeleteOne(); + } + + public void deleteAll() throws PersistException { + Log log = mStorage.mRepo.getLog(); + if (log.isEnabled()) { + log.write("Query.deleteAll() on " + this); + } + super.deleteAll(); + } + + protected S wrap(S storable) { + return mStorage.wrap(storable); + } + + protected WrappedQuery newInstance(Query query) { + return new LoggingQuery(mStorage, query); + } +} diff --git a/src/main/java/com/amazon/carbonado/repo/logging/LoggingRepository.java b/src/main/java/com/amazon/carbonado/repo/logging/LoggingRepository.java new file mode 100644 index 0000000..e44e3b7 --- /dev/null +++ b/src/main/java/com/amazon/carbonado/repo/logging/LoggingRepository.java @@ -0,0 +1,114 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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 com.amazon.carbonado.repo.logging; + +import java.util.IdentityHashMap; +import java.util.Map; + +import com.amazon.carbonado.IsolationLevel; +import com.amazon.carbonado.Repository; +import static com.amazon.carbonado.RepositoryBuilder.RepositoryReference; +import com.amazon.carbonado.RepositoryException; +import com.amazon.carbonado.Storable; +import com.amazon.carbonado.Storage; +import com.amazon.carbonado.SupportException; +import com.amazon.carbonado.Transaction; + +import com.amazon.carbonado.capability.Capability; + +/** + * + * + * @author Brian S O'Neill + */ +class LoggingRepository implements Repository, LogAccessCapability { + private final RepositoryReference mRootRef; + private final Repository mRepo; + private final Log mLog; + + // Map of storages by storable class + private final Map, LoggingStorage> mStorages; + + LoggingRepository(RepositoryReference rootRef, Repository actual, Log log) { + mRootRef = rootRef; + mRepo = actual; + mLog = log; + + mStorages = new IdentityHashMap, LoggingStorage>(); + } + + public String getName() { + return mRepo.getName(); + } + + public Storage storageFor(Class type) + throws SupportException, RepositoryException + { + synchronized (mStorages) { + LoggingStorage storage = mStorages.get(type); + if (storage == null) { + storage = new LoggingStorage(this, mRepo.storageFor(type)); + mStorages.put(type, storage); + } + return storage; + } + } + + public Transaction enterTransaction() { + mLog.write("Repository.enterTransaction()"); + return new LoggingTransaction(mLog, mRepo.enterTransaction()); + } + + public Transaction enterTransaction(IsolationLevel level) { + if (mLog.isEnabled()) { + mLog.write("Repository.enterTransaction(" + level + ')'); + } + return new LoggingTransaction(mLog, mRepo.enterTransaction(level)); + } + + public Transaction enterTopTransaction(IsolationLevel level) { + if (mLog.isEnabled()) { + mLog.write("Repository.enterTopTransaction(" + level + ')'); + } + return new LoggingTransaction(mLog, mRepo.enterTopTransaction(level)); + } + + public IsolationLevel getTransactionIsolationLevel() { + return mRepo.getTransactionIsolationLevel(); + } + + public C getCapability(Class capabilityType) { + if (capabilityType.isInstance(this)) { + return (C) this; + } + return mRepo.getCapability(capabilityType); + } + + public void close() { + mRepo.close(); + } + + public Log getLog() { + return mLog; + } + + Repository getRootRepository() { + return mRootRef.get(); + } +} diff --git a/src/main/java/com/amazon/carbonado/repo/logging/LoggingRepositoryBuilder.java b/src/main/java/com/amazon/carbonado/repo/logging/LoggingRepositoryBuilder.java new file mode 100644 index 0000000..5f06cd5 --- /dev/null +++ b/src/main/java/com/amazon/carbonado/repo/logging/LoggingRepositoryBuilder.java @@ -0,0 +1,150 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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 com.amazon.carbonado.repo.logging; + +import java.util.Collection; + +import com.amazon.carbonado.ConfigurationException; +import com.amazon.carbonado.Repository; +import com.amazon.carbonado.RepositoryBuilder; +import com.amazon.carbonado.RepositoryException; + +import com.amazon.carbonado.spi.AbstractRepositoryBuilder; + +/** + * Repository implementation which logs activity against it. By default, all + * logged messages are at the debug level. + * + *

+ * The following extra capabilities are supported: + *

    + *
  • {@link LogAccessCapability} + *
+ * + * Example: + * + *
+ * LoggingRepositoryBuilder loggingBuilder = new LoggingRepositoryBuilder();
+ * loggingBuilder.setActualRepositoryBuilder(...);
+ * Repository repo = loggingBuilder.build();
+ * 
+ * + * @author Brian S O'Neill + */ +public class LoggingRepositoryBuilder extends AbstractRepositoryBuilder { + private String mName; + private Boolean mMaster; + private Log mLog; + private RepositoryBuilder mRepoBuilder; + + public LoggingRepositoryBuilder() { + } + + public Repository build(RepositoryReference rootRef) throws RepositoryException { + if (mName == null) { + if (mRepoBuilder != null) { + mName = mRepoBuilder.getName(); + } + } + + assertReady(); + + if (mLog == null) { + mLog = new CommonsLog(LoggingRepository.class); + } + + String originalName = mRepoBuilder.getName(); + boolean originalIsMaster = mRepoBuilder.isMaster(); + + boolean enabled = mLog.isEnabled(); + boolean master = mMaster != null ? mMaster : originalIsMaster; + + Repository actual; + try { + if (enabled) { + mRepoBuilder.setName("Logging " + mName); + } + mRepoBuilder.setMaster(master); + actual = mRepoBuilder.build(rootRef); + } finally { + mRepoBuilder.setName(originalName); + mRepoBuilder.setMaster(originalIsMaster); + } + + if (!enabled) { + return actual; + } + + Repository repo = new LoggingRepository(rootRef, actual, mLog); + rootRef.set(repo); + return repo; + } + + public void setName(String name) { + mName = name; + } + + public String getName() { + return mName; + } + + public void setMaster(boolean master) { + mMaster = master; + } + + public boolean isMaster() { + return mMaster; + } + + /** + * Set the Log to use. If null, use default. Log must be enabled when build + * is called, or else no logging is ever performed. + */ + public void setLog(Log log) { + mLog = log; + } + + /** + * Return the Log to use. If null, use default. + */ + public Log getLog() { + return mLog; + } + + /** + * Set the Repository to wrap all calls to. + */ + public void setActualRepositoryBuilder(RepositoryBuilder builder) { + mRepoBuilder = builder; + } + + /** + * Returns the Repository that all calls are wrapped to. + */ + public RepositoryBuilder getActualRepositoryBuilder() { + return mRepoBuilder; + } + + public void errorCheck(Collection messages) throws ConfigurationException { + super.errorCheck(messages); + if (mRepoBuilder == null) { + messages.add("Actual repository builder must be set"); + } + } +} diff --git a/src/main/java/com/amazon/carbonado/repo/logging/LoggingStorage.java b/src/main/java/com/amazon/carbonado/repo/logging/LoggingStorage.java new file mode 100644 index 0000000..93b5a33 --- /dev/null +++ b/src/main/java/com/amazon/carbonado/repo/logging/LoggingStorage.java @@ -0,0 +1,138 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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 com.amazon.carbonado.repo.logging; + +import com.amazon.carbonado.FetchException; +import com.amazon.carbonado.PersistException; +import com.amazon.carbonado.Query; +import com.amazon.carbonado.Repository; +import com.amazon.carbonado.Storable; +import com.amazon.carbonado.Storage; + +import com.amazon.carbonado.spi.WrappedStorage; + +/** + * + * + * @author Brian S O'Neill + */ +class LoggingStorage extends WrappedStorage { + final LoggingRepository mRepo; + + LoggingStorage(LoggingRepository repo, Storage storage) { + super(storage); + mRepo = repo; + } + + protected S wrap(S storable) { + return super.wrap(storable); + } + + protected Query wrap(Query query) { + return new LoggingQuery(this, query); + } + + protected Support createSupport(S storable) { + return new Handler(storable); + } + + private class Handler extends Support { + private final S mStorable; + + Handler(S storable) { + mStorable = storable; + } + + public Repository getRootRepository() { + return mRepo.getRootRepository(); + } + + public boolean isPropertySupported(String propertyName) { + return mStorable.isPropertySupported(propertyName); + } + + public void load() throws FetchException { + Log log = mRepo.getLog(); + if (log.isEnabled()) { + log.write("Storable.load() on " + mStorable.toStringKeyOnly()); + } + mStorable.load(); + } + + public boolean tryLoad() throws FetchException { + Log log = mRepo.getLog(); + if (log.isEnabled()) { + log.write("Storable.tryLoad() on " + mStorable.toStringKeyOnly()); + } + return mStorable.tryLoad(); + } + + public void insert() throws PersistException { + Log log = mRepo.getLog(); + if (log.isEnabled()) { + log.write("Storable.insert() on " + mStorable.toString()); + } + mStorable.insert(); + } + + public boolean tryInsert() throws PersistException { + Log log = mRepo.getLog(); + if (log.isEnabled()) { + log.write("Storable.tryInsert() on " + mStorable.toString()); + } + return mStorable.tryInsert(); + } + + public void update() throws PersistException { + Log log = mRepo.getLog(); + if (log.isEnabled()) { + log.write("Storable.update() on " + mStorable.toString()); + } + mStorable.update(); + } + + public boolean tryUpdate() throws PersistException { + Log log = mRepo.getLog(); + if (log.isEnabled()) { + log.write("Storable.tryUpdate() on " + mStorable.toString()); + } + return mStorable.tryUpdate(); + } + + public void delete() throws PersistException { + Log log = mRepo.getLog(); + if (log.isEnabled()) { + log.write("Storable.delete() on " + mStorable.toStringKeyOnly()); + } + mStorable.delete(); + } + + public boolean tryDelete() throws PersistException { + Log log = mRepo.getLog(); + if (log.isEnabled()) { + log.write("Storable.tryDelete() on " + mStorable.toStringKeyOnly()); + } + return mStorable.tryDelete(); + } + + public Support createSupport(S storable) { + return new Handler(storable); + } + } +} diff --git a/src/main/java/com/amazon/carbonado/repo/logging/LoggingTransaction.java b/src/main/java/com/amazon/carbonado/repo/logging/LoggingTransaction.java new file mode 100644 index 0000000..7deac92 --- /dev/null +++ b/src/main/java/com/amazon/carbonado/repo/logging/LoggingTransaction.java @@ -0,0 +1,69 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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 com.amazon.carbonado.repo.logging; + +import java.util.concurrent.TimeUnit; + +import com.amazon.carbonado.IsolationLevel; +import com.amazon.carbonado.PersistException; +import com.amazon.carbonado.Transaction; + +/** + * + * + * @author Brian S O'Neill + */ +class LoggingTransaction implements Transaction { + private final Log mLog; + private final Transaction mTxn; + + LoggingTransaction(Log log, Transaction txn) { + mLog = log; + mTxn = txn; + } + + public void commit() throws PersistException { + mLog.write("Transaction.commit()"); + mTxn.commit(); + } + + public void exit() throws PersistException { + mLog.write("Transaction.exit()"); + mTxn.exit(); + } + + public void setForUpdate(boolean forUpdate) { + if (mLog.isEnabled()) { + mLog.write("Transaction.setForUpdate(" + forUpdate + ')'); + } + mTxn.setForUpdate(forUpdate); + } + + public boolean isForUpdate() { + return mTxn.isForUpdate(); + } + + public void setDesiredLockTimeout(int timeout, TimeUnit unit) { + mTxn.setDesiredLockTimeout(timeout, unit); + } + + public IsolationLevel getIsolationLevel() { + return mTxn.getIsolationLevel(); + } +} diff --git a/src/main/java/com/amazon/carbonado/repo/logging/package-info.java b/src/main/java/com/amazon/carbonado/repo/logging/package-info.java new file mode 100644 index 0000000..860a9ae --- /dev/null +++ b/src/main/java/com/amazon/carbonado/repo/logging/package-info.java @@ -0,0 +1,25 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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. + */ + +/** + * Repository implementation which logs activity against it. By default, all + * logged messages are at the debug level. + * + * @see com.amazon.carbonado.repo.logging.LoggingRepositoryBuilder + */ +package com.amazon.carbonado.repo.logging; -- cgit v1.2.3