[Major] Multiple issues

- Documented ComponentContainer.getComponent()
- StrolchRealm try lock timeout is configurable
- added DataStoreMode.isTransient()
- documented Command
- fixed lower case name attributes in Enums.xml
This commit is contained in:
Robert von Burg 2014-03-03 23:30:35 +01:00
parent 66e70fce75
commit c7cb42724e
7 changed files with 118 additions and 22 deletions

View File

@ -31,7 +31,7 @@ public interface ComponentContainer {
public abstract boolean hasComponent(Class<?> clazz);
public abstract <T> T getComponent(Class<T> clazz);
public abstract <T> T getComponent(Class<T> clazz) throws IllegalArgumentException;
public abstract Set<Class<?>> getComponentTypes();

View File

@ -15,17 +15,22 @@
*/
package li.strolch.agent.api;
import static ch.eitchnet.utils.helper.StringHelper.DOT;
import java.util.concurrent.TimeUnit;
import li.strolch.agent.impl.DataStoreMode;
import li.strolch.agent.impl.DefaultLockHandler;
import li.strolch.model.StrolchRootElement;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.runtime.StrolchConstants;
import li.strolch.runtime.configuration.ComponentConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.eitchnet.utils.dbc.DBC;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
@ -38,6 +43,7 @@ public abstract class StrolchRealm {
private LockHandler lockHandler;
public StrolchRealm(String realm) {
DBC.PRE.assertNotEmpty("RealmName may not be empty!", realm);
this.realm = realm;
}
@ -46,6 +52,7 @@ public abstract class StrolchRealm {
}
public void lock(StrolchRootElement element) {
DBC.PRE.assertNotNull("Can not lock a null pointer =)", element);
this.lockHandler.lock(element);
}
@ -54,8 +61,16 @@ public abstract class StrolchRealm {
}
public void initialize(ComponentContainer container, ComponentConfiguration configuration) {
TimeUnit timeUnit = TimeUnit.valueOf(configuration.getString(PROP_TRY_LOCK_TIME_UNIT, TimeUnit.SECONDS.name()));
long time = configuration.getLong(PROP_TRY_LOCK_TIME, 10);
String propTryLockTimeUnit = PROP_TRY_LOCK_TIME_UNIT;
String propTryLockTime = PROP_TRY_LOCK_TIME;
if (!StrolchConstants.DEFAULT_REALM.equals(this.realm)) {
propTryLockTimeUnit += DOT + this.realm;
propTryLockTime += DOT + this.realm;
}
TimeUnit timeUnit = TimeUnit.valueOf(configuration.getString(propTryLockTimeUnit, TimeUnit.SECONDS.name()));
long time = configuration.getLong(propTryLockTime, 10);
logger.info("Using a locking try timeout of " + timeUnit.toSeconds(time) + "s");
this.lockHandler = new DefaultLockHandler(realm, timeUnit, time);
}

View File

@ -74,7 +74,7 @@ public class ComponentContainerImpl implements ComponentContainer {
@Override
@SuppressWarnings("unchecked")
public <T> T getComponent(Class<T> clazz) {
public <T> T getComponent(Class<T> clazz) throws IllegalArgumentException {
T component = (T) this.componentMap.get(clazz);
if (component == null) {
String msg = "The component does not exist for class {0}"; //$NON-NLS-1$

View File

@ -25,24 +25,44 @@ import li.strolch.agent.api.StrolchRealm;
*/
public enum DataStoreMode {
EMPTY {
@Override
public boolean isTransient() {
return true;
}
@Override
public StrolchRealm createRealm(String realm) {
return new EmptyRealm(realm);
}
}, //
TRANSIENT {
@Override
public boolean isTransient() {
return true;
}
@Override
public StrolchRealm createRealm(String realm) {
return new TransientRealm(realm);
}
}, //
CACHED {
@Override
public boolean isTransient() {
return false;
}
@Override
public StrolchRealm createRealm(String realm) {
return new CachedRealm(realm);
}
}, //
TRANSACTIONAL {
@Override
public boolean isTransient() {
return false;
}
@Override
public StrolchRealm createRealm(String realm) {
return new TransactionalRealm(realm);
@ -51,6 +71,8 @@ public enum DataStoreMode {
public abstract StrolchRealm createRealm(String realm);
public abstract boolean isTransient();
public static DataStoreMode parseDataStoreMode(String modeS) {
for (DataStoreMode dataStoreMode : values()) {
if (dataStoreMode.name().endsWith(modeS))

View File

@ -258,6 +258,11 @@ public abstract class AbstractTransaction implements StrolchTransaction {
} catch (Exception e1) {
handleFailure(start, e);
}
String msg = "Strolch Transaction for realm {0} failed due to {1}";
msg = MessageFormat.format(msg, getRealmName(), e.getMessage());
throw new StrolchPersistenceException(msg, e);
} finally {
unlockElements();
}
@ -334,8 +339,9 @@ public abstract class AbstractTransaction implements StrolchTransaction {
sb.append(StringHelper.formatNanoDuration(closeDuration));
logger.info(sb.toString());
throw new StrolchPersistenceException(
"Strolch Transaction for realm " + getRealmName() + " failed due to " + e.getMessage(), e); //$NON-NLS-1$
String msg = "Strolch Transaction for realm {0} failed due to {1}";
msg = MessageFormat.format(msg, getRealmName(), e.getMessage());
throw new StrolchPersistenceException(msg, e);
}
private void updateObservers() {

View File

@ -16,6 +16,7 @@
package li.strolch.service.api;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.agent.api.StrolchComponent;
import li.strolch.persistence.api.StrolchTransaction;
import org.slf4j.Logger;
@ -24,6 +25,16 @@ import org.slf4j.LoggerFactory;
import ch.eitchnet.privilege.model.Restrictable;
/**
* <p>
* Implementation of the Command Pattern to create re-usable components which are performed during
* {@link StrolchTransaction StrolchTransactions} as part of the execution of {@link Service Services}
* </p>
*
* <p>
* <b>Note:</b> Do not call {@link #doCommand()} from {@link Service Services} or other places. Add {@link Command}
* instances to a {@link StrolchTransaction} by calling {@link StrolchTransaction#addCommand(Command)}
* </p>
*
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public abstract class Command implements Restrictable {
@ -32,12 +43,31 @@ public abstract class Command implements Restrictable {
private final ComponentContainer container;
private final StrolchTransaction tx;
/**
* Instantiate a new {@link Command}
*
* @param container
* the {@link ComponentContainer} to access components at runtime
* @param tx
*/
public Command(ComponentContainer container, StrolchTransaction tx) {
this.container = container;
this.tx = tx;
}
public <V> V getComponent(Class<V> clazz) {
/**
* Allows the concrete {@link Command} implementation access to {@link StrolchComponent StrolchComponents} at
* runtime
*
* @param clazz
* the type of component to be returned
*
* @return the component with the given {@link Class} which is registered on the {@link ComponentContainer}
*
* @throws IllegalArgumentException
* if the component with the given class does not exist
*/
protected <V> V getComponent(Class<V> clazz) throws IllegalArgumentException {
return this.container.getComponent(clazz);
}
@ -73,9 +103,32 @@ public abstract class Command implements Restrictable {
return this.getClass().getName();
}
/**
* To ensure that as few possibilities for exceptions as possible occur when {@link #doCommand()} is called, the
* {@link Command} should verify any input data so that a {@link #doCommand()} can be performed without exceptions
*/
public abstract void validate();
/**
* <p>
* Clients implement this method to perform the work which is to be done in this {@link Command}.
* </p>
*
* <p>
* <b>Note:</b> Do not call this method directly, this method is called by the {@link StrolchTransaction} when the
* transaction is committed. Add this {@link Command} to the transaction by calling
* {@link StrolchTransaction#addCommand(Command)}
* </p>
*/
public abstract void doCommand();
/**
* <p>
* Should the transaction fail, either due to a {@link Command} throwing an exception when {@link #validate()} is
* called, or while committing the transaction, then this method should properly undo any changes it has done. It is
* imperative that this method does not throw further exceptions and that the state to be rolled back is remembered
* in the Command during committing
* </p>
*/
public abstract void undo();
}

View File

@ -3,31 +3,31 @@
<Resource Id="salutations" Name="Salutations" Type="Enumeration">
<ParameterBag Id="en" Name="Salutations" Type="Enumeration">
<Parameter Id="mr" name="Mr" Type="String" Value="Mr" />
<Parameter Id="mrs" name="Mrs" Type="String" Value="Mrs" />
<Parameter Id="ms" name="Ms" Type="String" Value="Ms" />
<Parameter Id="mr" Name="Mr" Type="String" Value="Mr" />
<Parameter Id="mrs" Name="Mrs" Type="String" Value="Mrs" />
<Parameter Id="ms" Name="Ms" Type="String" Value="Ms" />
</ParameterBag>
</Resource>
<Resource Id="sex" Name="Sex" Type="Enumeration">
<ParameterBag Id="en" Name="Sex" Type="Enumeration">
<Parameter Id="male" name="Male" Type="String" Value="male" />
<Parameter Id="female" name="Female" Type="String" Value="female" />
<Parameter Id="both" name="Both" Type="String" Value="both" />
<Parameter Id="male" Name="Male" Type="String" Value="male" />
<Parameter Id="female" Name="Female" Type="String" Value="female" />
<Parameter Id="both" Name="Both" Type="String" Value="both" />
</ParameterBag>
</Resource>
<Resource Id="religions" Name="Religions" Type="Enumeration">
<ParameterBag Id="en" Name="Religions" Type="Enumeration">
<Parameter Id="Roman Catholic" name="Roman Catholic" Type="String" Value="Roman Catholic" />
<Parameter Id="Protestant" name="Protestant" Type="String" Value="Protestant" />
<Parameter Id="Orthodox" name="Orthodox" Type="String" Value="Orthodox" />
<Parameter Id="Christian" name="Anglican" Type="String" Value="Anglican" />
<Parameter Id="Muslim" name="Muslim" Type="String" Value="Muslim" />
<Parameter Id="Hindu" name="Hindu" Type="String" Value="Hindu" />
<Parameter Id="Buddhist" name="Buddhist" Type="String" Value="Buddhist" />
<Parameter Id="Jewish" name="Jewish" Type="String" Value="Jewish" />
<Parameter Id="Atheist" name="Atheist" Type="String" Value="Atheist" />
<Parameter Id="Roman Catholic" Name="Roman Catholic" Type="String" Value="Roman Catholic" />
<Parameter Id="Protestant" Name="Protestant" Type="String" Value="Protestant" />
<Parameter Id="Orthodox" Name="Orthodox" Type="String" Value="Orthodox" />
<Parameter Id="Christian" Name="Anglican" Type="String" Value="Anglican" />
<Parameter Id="Muslim" Name="Muslim" Type="String" Value="Muslim" />
<Parameter Id="Hindu" Name="Hindu" Type="String" Value="Hindu" />
<Parameter Id="Buddhist" Name="Buddhist" Type="String" Value="Buddhist" />
<Parameter Id="Jewish" Name="Jewish" Type="String" Value="Jewish" />
<Parameter Id="Atheist" Name="Atheist" Type="String" Value="Atheist" />
</ParameterBag>
</Resource>