Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.servicerocket.confluence.randombits.storage.BasedStorage Maven / Gradle / Ivy
/*
* Copyright (c) 2006, David Peterson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of "randombits.org" nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package com.servicerocket.confluence.randombits.storage;
import java.util.*;
/**
* Subclasses of this implementation are intended to have a base storage
* location underlying it.
*
* @author David Peterson
*/
public abstract class BasedStorage extends AbstractStorage {
/**
* Used to define how boxes are opened and closed.
*/
public enum BoxType {
/**
* Every {@link BasedStorage#openBox(String)} call creates a new
* {@link Map} to store its values in.
*/
Real,
/**
* Every {@link BasedStorage#openBox(String)} call modifies the path
* that values are set or retrieved from from the base {@link Map}.
*/
Virtual
}
// The current box. If null, we're at the root.
private Map box;
private Stack> boxes;
private String topBoxName;
private BoxType boxType;
/**
* Constructs a new storage object. {@link BoxType#Virtual} builds the
* property path as a string with each box separated by a {@link #SEPARATOR},
* while {@link BoxType#Real} creates a new Map for each box.
*
* @param boxType The type.
*/
public BasedStorage(BoxType boxType) {
this.boxType = boxType;
}
/**
* Returns the name set for the base object.
*
* @return The name set, or null
if the set is not available.
*/
protected abstract Set baseNameSet();
@Override
public void openBox(String name) {
super.openBox(name);
if (boxType == BoxType.Real) {
Map newBox = getObject(name, null, Map.class);
if (newBox == null) {
newBox = createBox();
}
if (box != null) {
if (boxes == null) {
boxes = new Stack<>();
}
box.put(name, newBox);
boxes.push(box);
}
box = newBox;
}
if (topBoxName == null) {
topBoxName = name;
}
}
/**
* Creates a new box when in {@link BoxType#Real} mode. Subclasses should
* override this if they wish to change the type of Map used for the box.
*
* @return The new Map for the box.
*/
protected Map createBox() {
return new HashMap<>();
}
@Override
public void closeBox() {
super.closeBox();
if (boxType == BoxType.Real) {
if (boxes != null && boxes.size() != 0) {
box = boxes.pop();
} else {
if (!isReadOnly()) {
setBaseObject(topBoxName, box);
}
box = null;
topBoxName = null;
}
}
}
/**
* Retrieves a Boolean from the base object.
*
* @param string The name of the boolean value.
* @return the Boolean value for the specified name.
*/
protected abstract Boolean getBaseBoolean(String string);
/**
* Retrieves the named DateTime value from the base object.
*
* @param name The name of the value.
* @return The value.
* @throws StorageException if there is a problem retrieving the date.
*/
protected abstract Date getBaseDate(String name);
/**
* Retrieves the double value from the base object.
*
* @param name The name of the value.
* @return The value.
*/
protected abstract Double getBaseDouble(String name);
/**
* Returns an integer from the base object.
*
* @param name The named value.
* @return The integer object, or null
.
*/
protected abstract Integer getBaseInteger(String name);
/**
* Returns the named value as a Long.
*
* @param name The name of the value.
* @return The value as a long.
*/
protected abstract Long getBaseLong(String name);
/**
* Returns the named value as a Number. Useful if the specific type of
* number in the field is unknown.
*
* @param name The name of the value.
* @return The value as a Number.
*/
protected abstract Number getBaseNumber(String name);
/**
* Returns an object stored with the specified name.
*
* @param name The name of the value to return.
* @return the stored object.
*/
protected abstract Object getBaseObject(String name);
/**
* Retrieves the object list from the underlying base object.
*
* @param name The name of the stored list.
* @return The list.
*/
protected abstract List getBaseObjectList(String name);
/**
* Returns the named string value from the base object.
*
* @param name The name of the string to return.
* @return the string value, or null
.
*/
protected abstract String getBaseString(String name);
/**
* Returns the string array from the underlying base object.
*
* @param name The name of the value.
* @return The string array.
* @throws StorageException if there is a problem retrieving the value.
*/
protected abstract String[] getBaseStringArray(String name) throws StorageException;
protected T getBoxValue(String name, Class clazz) {
Object value = box.get(name);
return toType(value, null, clazz);
}
@Override
public Boolean getBoolean(String name, Boolean def) {
try {
Boolean value;
if (boxType == BoxType.Real) {
if (box == null) {
value = getBaseBoolean(name);
} else {
value = getBoxValue(name, Boolean.class);
}
} else {
value = getBaseBoolean(makePath(name));
}
if (value == null) {
return def;
}
return value;
} catch (ClassCastException e) {
throw new StorageException(makePath(name), e);
}
}
@Override
public Date getDate(String name, Date def) {
try {
Date value;
if (boxType == BoxType.Real) {
if (box == null) {
value = getBaseDate(name);
} else {
value = getBoxValue(name, Date.class);
}
} else {
value = getBaseDate(makePath(name));
}
if (value == null) {
return def;
}
return value;
} catch (ClassCastException e) {
throw new StorageException(makePath(name), e);
}
}
@Override
public Double getDouble(String name, Double def) {
try {
Double value;
if (boxType == BoxType.Real) {
if (box != null) {
Number number = getBoxValue(name, Number.class);
value = number != null ? number.doubleValue() : null;
} else {
value = getBaseDouble(name);
}
} else {
value = getBaseDouble(makePath(name));
}
if (value == null) {
return def;
}
return value;
} catch (ClassCastException e) {
throw new StorageException(makePath(name), e);
}
}
@Override
public Integer getInteger(String name, Integer def) {
try {
Integer value;
if (boxType == BoxType.Real) {
if (box != null) {
Number number = getBoxValue(name, Number.class);
value = number != null ? number.intValue() : null;
} else {
value = getBaseInteger(name);
}
} else {
value = getBaseInteger(makePath(name));
}
if (value == null) {
return def;
}
return value;
} catch (ClassCastException e) {
throw new StorageException(makePath(name), e);
}
}
@Override
public Long getLong(String name, Long def) {
try {
Long value;
if (boxType == BoxType.Real) {
if (box != null) {
Number number = getBoxValue(name, Number.class);
value = number != null ? number.longValue() : null;
} else {
value = getBaseLong(name);
}
} else {
value = getBaseLong(makePath(name));
}
if (value == null) {
return def;
}
return value;
} catch (ClassCastException e) {
throw new StorageException(makePath(name), e);
}
}
/**
* Returns the named value as a {@link Number}. What the actual type of
* Number returned is depends on both the stored value, type of
* {@link Storage} and the default value. Assume
* nothing.
*
* @param name The name of the value to return.
* @param def The value to return if no value is stored.
* @return The stored value, or the default if nothing is stord with that.
*/
public Number getNumber(String name, Number def) {
try {
Number value;
if (boxType == BoxType.Real) {
if (box != null) {
value = getBoxValue(name, Number.class);
} else {
value = getBaseNumber(name);
}
} else {
value = getBaseNumber(makePath(name));
}
if (value == null) {
return def;
}
return value;
} catch (ClassCastException e) {
throw new StorageException(makePath(name), e);
}
}
@Override
public T getObject(String name, T def, Class type) {
Object value;
if (boxType == BoxType.Real) {
if (box == null) {
value = getBaseObject(name);
} else {
value = box.get(name);
}
} else {
value = getBaseObject(makePath(name));
}
return toType(value, def, type);
}
protected T toType(Object value, T def, Class type) {
if (type.isInstance(value)) {
return (T) value;
}
return def;
}
@Override
public List getObjectList(String name, List def) {
List value;
if (boxType == BoxType.Real) {
if (box == null) {
value = getBaseObjectList(name);
} else {
value = getBoxValue(name, List.class);
}
} else {
value = getBaseObjectList(makePath(name));
}
if (value == null) {
return def;
}
return value;
}
@Override
public String getString(String name, String def) {
try {
String value;
if (boxType == BoxType.Real) {
if (box == null) {
value = getBaseString(name);
} else {
value = getBoxValue(name, String.class);
}
} else {
value = getBaseString(makePath(name));
}
if (value == null) {
return def;
}
return value;
} catch (ClassCastException e) {
throw new StorageException(makePath(name), e);
}
}
@Override
public String[] getStringArray(String name, String[] def) {
try {
String[] value;
if (boxType == BoxType.Real) {
if (box == null) {
value = getBaseStringArray(name);
} else {
value = getBoxValue(name, String[].class);
}
} else {
value = getBaseStringArray(makePath(name));
}
if (value == null) {
return def;
}
return value;
} catch (ClassCastException e) {
throw new StorageException(makePath(name), e);
}
}
@Override
public Set nameSet() {
if (box == null) {
return baseNameSet();
} else {
return box.keySet();
}
}
/**
* Sets the named boolean value in the base object.
*
* @param name The name of the value.
* @param value The value being set.
*/
protected abstract void setBaseBoolean(String name, Boolean value);
/**
* Stores the named date value in the base object.
*
* @param name The name of the value.
* @param value The Date value being set.
*/
protected abstract void setBaseDate(String name, Date value);
/**
* Sets the named double value in the base object.
*
* @param name The name of the value.
* @param value The value being set.
*/
protected abstract void setBaseDouble(String name, Double value);
/**
* Sets the integer in the base object.
*
* @param name The name of the value.
* @param value The integer value to set.
*/
protected abstract void setBaseInteger(String name, Integer value);
/**
* Sets the long in the base object.
*
* @param name The name of the value.
* @param value The long value to set.
*/
protected abstract void setBaseLong(String name, Long value);
/**
* Sets the object in the base object.
*
* @param name The name of the value.
* @param value The object value to set.
*/
protected abstract void setBaseObject(String name, Object value);
/**
* Stores the list into the base object.
*
* @param name The name to store with.
* @param value The value to store.
*/
protected abstract void setBaseObjectList(String name, List value);
/**
* Set the string value in the base object.
*
* @param name The name of the value.
* @param value The value to set.
*/
protected abstract void setBaseString(String name, String value);
/**
* Sets the string array in the underlying base object.
*
* @param name The name to store the value as.
* @param value The value to store.
*/
protected abstract void setBaseStringArray(String name, String[] value);
@Override
public void setBoolean(String name, Boolean value) {
checkReadOnly();
if (boxType == BoxType.Real) {
if (box == null) {
setBaseBoolean(name, value);
} else {
box.put(name, value);
}
} else {
setBaseBoolean(makePath(name), value);
}
}
@Override
public void setDate(String name, Date value) {
checkReadOnly();
if (boxType == BoxType.Real) {
if (box == null) {
setBaseDate(name, value);
} else {
box.put(name, value);
}
} else {
setBaseDate(makePath(name), value);
}
}
@Override
public void setDouble(String name, Double value) {
checkReadOnly();
if (boxType == BoxType.Real) {
if (box == null) {
setBaseDouble(name, value);
} else {
box.put(name, value);
}
} else {
setBaseDouble(makePath(name), value);
}
}
@Override
public void setInteger(String name, Integer value) {
checkReadOnly();
if (boxType == BoxType.Real) {
if (box == null) {
setBaseInteger(name, value);
} else {
box.put(name, value);
}
} else {
setBaseInteger(makePath(name), value);
}
}
@Override
public void setLong(String name, Long value) {
checkReadOnly();
if (boxType == BoxType.Real) {
if (box == null) {
setBaseLong(name, value);
} else {
box.put(name, value);
}
} else {
setBaseLong(makePath(name), value);
}
}
/**
* Stores the object value with with the specified name.
*
* @param name The name to store against.
* @param value The value to store.
*/
@Override
public void setObject(String name, Object value) {
checkReadOnly();
if (boxType == BoxType.Real) {
if (box == null) {
setBaseObject(name, value);
} else {
box.put(name, value);
}
} else {
setBaseObject(makePath(name), value);
}
}
@Override
public void setObjectList(String name, List value) {
checkReadOnly();
if (boxType == BoxType.Real) {
if (box == null) {
setBaseObjectList(name, value);
} else {
box.put(name, value);
}
} else {
setBaseObjectList(makePath(name), value);
}
}
@Override
public void setString(String name, String value) {
checkReadOnly();
if (boxType == BoxType.Real) {
if (box == null) {
setBaseString(name, value);
} else {
box.put(name, value);
}
} else {
setBaseString(makePath(name), value);
}
}
@Override
public void setStringArray(String name, String[] value) {
checkReadOnly();
if (boxType == BoxType.Real) {
if (box == null) {
setBaseStringArray(name, value);
} else {
box.put(name, value);
}
} else {
setBaseStringArray(makePath(name), value);
}
}
public boolean removeBox(String name) {
checkReadOnly();
if (boxType == BoxType.Real) {
Map box = (Map) getBaseObject(name);
if (box != null) {
setBaseObject(name, null);
}
return true;
}
return false;
}
}