/*
* Copyright (c) 2010, WSO2 Inc. (http://www.wso2.org) 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 org.wso2.carbon.registry.jcr;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.registry.core.CollectionImpl;
import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.jcr.nodetype.RegistryPropertyDefinition;
import org.wso2.carbon.registry.jcr.util.RegistryJCRItemOperationUtil;
import org.wso2.carbon.registry.jcr.util.RegistryJCRSpecificStandardLoderUtil;
import javax.jcr.*;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.version.VersionException;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
public class RegistryProperty implements Property {
RegistryValue value;
Value[] values;
String[] stringMultipleVals;
private String name;
// private CollectionImpl collectionP; //a collection which has the required property
private RegistrySession session;
private boolean isResource = false;
// private Resource collectionR = null;
private static Log log = LogFactory.getLog(RegistryNode.class);
private String path = "";
public RegistryProperty(RegistryNode node, String name) {
this.name = name;
}
public RegistryProperty(String path, RegistrySession session, String name, String value) {
this.path = path;
this.session = session;
this.name = name;
setQValue(value);
}
public RegistryProperty(String path, RegistrySession session, String name, String[] values) {
this.path = path;
this.session = session;
this.name = name;
setQValue(values);
}
public RegistryProperty(String path, RegistrySession session, String name, Node node) {
this.path = path;
this.session = session;
this.name = name;
setQValue(node);
}
public RegistryProperty(String path, RegistrySession session, String name, Binary binary) {
this.path = path;
this.session = session;
this.name = name;
setQValue(binary);
}
public RegistryProperty(String path, RegistrySession session, String name, BigDecimal bg) {
isResource = true;
this.path = path;
this.session = session;
this.name = name;
setQValue(bg);
}
public RegistryProperty(String path, RegistrySession session, String name, Calendar calendar) {
isResource = true;
this.path = path;
this.session = session;
this.name = name;
setQValue(calendar);
}
public RegistryProperty(String path, RegistrySession session, String name, InputStream inputStream) {
isResource = true;
this.path = path;
this.session = session;
this.name = name;
setQValue(inputStream);
}
public RegistryProperty(String path, RegistrySession session, String name, Value val) {
isResource = true;
this.path = path;
this.session = session;
this.name = name;
setQValue(val);
}
public RegistryProperty(String path, RegistrySession session, String name, Value[] vals) {
isResource = true;
this.path = path;
this.session = session;
this.name = name;
setQValue(vals);
}
public RegistryProperty(String path, RegistrySession session, String name, boolean val) {
isResource = true;
this.path = path;
this.session = session;
this.name = name;
setQValue(val);
}
public RegistryProperty(String path, RegistrySession session, String name, double val) {
isResource = true;
this.path = path;
this.session = session;
this.name = name;
setQValue(val);
}
public RegistryProperty(String path, RegistrySession session, String name, long val) {
isResource = true;
this.path = path;
this.session = session;
this.name = name;
setQValue(val);
}
private void validatePropertyModifyPrivilege() throws RepositoryException {
// This is a already set property , so setValue is a modification
if (RegistryJCRSpecificStandardLoderUtil.isSessionReadOnly(session.getUserID())) {
throw new AccessDeniedException("A read only session must not be allowed to modify a property value");
}
}
public void setValue(Value value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
RegistryJCRItemOperationUtil.checkRetentionPolicy(session,getPath());
validatePropertyModifyPrivilege();
if (value != null) {
this.value = (RegistryValue) value;
persistNewPropertyValue("value", value);
} else {
remove();
}
}
public void setQValue(Value value) {
if (value != null) {
this.value = (RegistryValue) value;
} else {
try {
remove();
} catch (RepositoryException e) {
log.error("Error occur while removing the value ");
}
}
}
public void setValue(Value[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
RegistryJCRItemOperationUtil.checkRetentionPolicy(session, getNodePath());
RegistryJCRItemOperationUtil.checkRetentionHold(session, getNodePath());
validatePropertyModifyPrivilege();
if (values != null) {
this.values = Arrays.copyOf(values, values.length);
setValuesToProperty(values);
} else {
remove();
}
}
public void setQValue(Value[] values) {
if (values != null) {
this.values = Arrays.copyOf(values, values.length);
} else {
try {
remove();
} catch (RepositoryException e) {
log.error("Error occur while removing the value ");
}
}
}
public void setValue(String s) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
RegistryJCRItemOperationUtil.checkRetentionPolicy(session, getNodePath());
RegistryJCRItemOperationUtil.checkRetentionHold(session, getNodePath());
validatePropertyModifyPrivilege();
value = new RegistryValue(s);
persistNewPropertyValue("string",s);
}
private void setQValue(String s) {
value = new RegistryValue(s);
}
public void setValue(String[] strings) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
RegistryJCRItemOperationUtil.checkRetentionPolicy(session, getNodePath());
validatePropertyModifyPrivilege();
stringMultipleVals = strings.clone();
values = new RegistryValue[strings.length];
int i = 0;
for (String s : strings) {
values[i] = new RegistryValue(s);
i++;
}
RegistryJCRItemOperationUtil.persistStringPropertyValues(session,path,name,strings);
}
private void setQValue(String[] strings) {
stringMultipleVals = strings.clone();
values = new RegistryValue[strings.length];
int i = 0;
for (String s : strings) {
values[i] = new RegistryValue(s);
i++;
}
}
public void setValue(InputStream inputStream) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
RegistryJCRItemOperationUtil.checkRetentionPolicy(session, getNodePath());
RegistryJCRItemOperationUtil.checkRetentionHold(session, getNodePath());
validatePropertyModifyPrivilege();
value = new RegistryValue(inputStream);
persistNewPropertyValue("is",inputStream);
}
private void setQValue(InputStream inputStream) {
value = new RegistryValue(inputStream);
}
public void setValue(Binary binary) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
RegistryJCRItemOperationUtil.checkRetentionPolicy(session, getNodePath());
RegistryJCRItemOperationUtil.checkRetentionHold(session, getNodePath());
validatePropertyModifyPrivilege();
value = new RegistryValue(binary);
//TODO persist binary type value
}
private void setQValue(Binary binary) {
value = new RegistryValue(binary);
}
public void setValue(long l) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
RegistryJCRItemOperationUtil.checkRetentionPolicy(session, getNodePath());
RegistryJCRItemOperationUtil.checkRetentionHold(session, getNodePath());
validatePropertyModifyPrivilege();
value = new RegistryValue(l);
persistNewPropertyValue("long",new Long(l));
}
private void setQValue(long l) {
value = new RegistryValue(l);
}
public void setValue(double v) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
RegistryJCRItemOperationUtil.checkRetentionPolicy(session, getNodePath());
RegistryJCRItemOperationUtil.checkRetentionHold(session, getNodePath());
validatePropertyModifyPrivilege();
value = new RegistryValue(v);
persistNewPropertyValue("double",new Double(v));
}
private void setQValue(double v) {
value = new RegistryValue(v);
}
public void setValue(BigDecimal bigDecimal) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
RegistryJCRItemOperationUtil.checkRetentionPolicy(session, getNodePath());
RegistryJCRItemOperationUtil.checkRetentionHold(session, getNodePath());
validatePropertyModifyPrivilege();
value = new RegistryValue(bigDecimal);
persistNewPropertyValue("big_d",bigDecimal);
}
private void setQValue(BigDecimal bigDecimal) {
value = new RegistryValue(bigDecimal);
}
public void setValue(Calendar calendar) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
RegistryJCRItemOperationUtil.checkRetentionPolicy(session, getNodePath());
RegistryJCRItemOperationUtil.checkRetentionHold(session, getNodePath());
validatePropertyModifyPrivilege();
if (calendar != null) {
value = new RegistryValue(calendar);
}
persistNewPropertyValue("calendar",calendar);
}
private void setQValue(Calendar calendar) {
if (calendar != null) {
value = new RegistryValue(calendar);
}
}
public void setValue(boolean b) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
RegistryJCRItemOperationUtil.checkRetentionPolicy(session, getNodePath());
RegistryJCRItemOperationUtil.checkRetentionHold(session, getNodePath());
validatePropertyModifyPrivilege();
value = new RegistryValue(b);
persistNewPropertyValue("boolean",String.valueOf(b));
}
private void setQValue(boolean b) {
value = new RegistryValue(b);
}
public void setValue(Node node) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
RegistryJCRItemOperationUtil.checkRetentionPolicy(session, getNodePath());
RegistryJCRItemOperationUtil.checkRetentionHold(session, getNodePath());
validatePropertyModifyPrivilege();
value = new RegistryValue(node);
//TODO set node type of values
}
private void setQValue(Node node) {
value = new RegistryValue(node);
}
public Value getValue() throws ValueFormatException, RepositoryException {
return value;
}
public Value[] getValues() throws ValueFormatException, RepositoryException {
if (values != null) {
return Arrays.copyOf(values, values.length);
} else {
throw new ValueFormatException("Invalid operation getValues for a single valued property");
}
}
public String getString() throws ValueFormatException, RepositoryException {
if (value != null) {
return value.getString();
} else {
return "";
}
}
public InputStream getStream() throws ValueFormatException, RepositoryException {
if (value != null) {
return value.getStream();
} else {
return new ByteArrayInputStream(new byte[]{12, 12, 22});
}
}
public Binary getBinary() throws ValueFormatException, RepositoryException {
if (value != null) {
return value.getBinary();
} else {
return null;
}
}
public long getLong() throws ValueFormatException, RepositoryException {
if (value != null) {
return value.getLong();
} else {
return 0;
}
}
public double getDouble() throws ValueFormatException, RepositoryException {
if (value != null) {
return value.getDouble();
} else {
return 0.0;
}
}
public BigDecimal getDecimal() throws ValueFormatException, RepositoryException {
if (value != null) {
return value.getDecimal();
} else {
return new BigDecimal(0);
}
}
public Calendar getDate() throws ValueFormatException, RepositoryException {
if (value != null) {
return value.getDate();
} else {
return null;
}
}
public boolean getBoolean() throws ValueFormatException, RepositoryException {
if (value != null) {
return value.getBoolean();
} else
return false;
}
public Node getNode() throws ItemNotFoundException, ValueFormatException, RepositoryException {
if (value != null) {
return value.getNode();
} else {
return null;
}
}
public Property getProperty() throws ItemNotFoundException, ValueFormatException, RepositoryException {
return this;
}
public long getLength() throws ValueFormatException, RepositoryException {
long length = 0;
if (value != null) {
length = value.toString().length();
}
return length;
}
public long[] getLengths() throws ValueFormatException, RepositoryException {
long[] lengths = new long[values.length]; //here only considers about strings,not binaries and all dat.
for (int i = 0; i < values.length; i++) {
lengths[i] = values[i].toString().length();
}
return lengths;
}
public PropertyDefinition getDefinition() throws RepositoryException {
return new RegistryPropertyDefinition();
}
public int getType() throws RepositoryException {
if(value != null) {
return value.getType();
} else if(values != null) {
return values[0].getType();
} else {
throw new RepositoryException("No such type for the property at " + path);
}
}
public boolean isMultiple() throws RepositoryException {
boolean isMul = false;
if (value != null) {
isMul = false;
} else if (values != null) {
isMul = true;
}
return isMul;
}
public String getPath() throws RepositoryException {
return path;
}
public String getName() throws RepositoryException {
return name;
}
public Item getAncestor(int i) throws ItemNotFoundException, AccessDeniedException, RepositoryException {
return session.getItem(RegistryJCRItemOperationUtil
.getAncestorPathAtGivenDepth(session,getPath(), i));
}
public Node getParent() throws ItemNotFoundException, AccessDeniedException, RepositoryException {
String parent = "";
if (isResource) {
try {
parent = session.getUserRegistry().get(path).getParentPath();
} catch (RegistryException e) {
log.error("Registry Exception occurred while obtaining " + path);
}
} else {
parent = path;
}
return (Node) session.getItem(parent);
}
public int getDepth() throws RepositoryException {
if (getPath().equals("/")) {
return 0;
} else {
return getPath().split("/").length - 4;
}
}
public RegistrySession getSession() throws RepositoryException {
return session;
}
public boolean isNode() {
boolean isNode = false;
if (value != null) {
Object propType = value.getKey();
if (propType instanceof Node) {
isNode = true;
}
}
return isNode;
}
public boolean isNew() {
boolean isNew = false;
if ((value != null) && (stringMultipleVals != null)) {
if (values == null) {
isNew = true;
}
}
return isNew;
}
public boolean isModified() {
return isPropertyResourceModified();
}
private boolean isPropertyResourceModified() {
boolean isModified = true;
try {
Resource resource = session.getUserRegistry().get(path);
if (!isResource) {
isModified = ((CollectionImpl) resource).isPropertiesModified();
}
} catch (RegistryException e) {
log.error("Registry exception occurred while checking content modification " + e);
}
return isModified;
}
public boolean isSame(Item item) throws RepositoryException {
boolean isSame = false;
if (name.equals(item.getName())) {
isSame = true;
}
return isSame;
}
public void accept(ItemVisitor itemVisitor) throws RepositoryException { //TODO
}
public void save() throws AccessDeniedException, ItemExistsException, ConstraintViolationException, InvalidItemStateException, ReferentialIntegrityException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException {//TODO
}
public void refresh(boolean b) throws InvalidItemStateException, RepositoryException { //TODO
}
public void remove() throws VersionException, LockException, ConstraintViolationException, AccessDeniedException, RepositoryException {
RegistryJCRItemOperationUtil.validateReadOnlyItemOpr(session);
RegistryJCRItemOperationUtil.checkRetentionPolicy(session, getNodePath());
RegistryJCRItemOperationUtil.checkRetentionHold(session, getNodePath());
try {
if (isResource) {
session.getUserRegistry().delete(path);
} else {
Resource node = session.getUserRegistry().get(path);
node.removeProperty(name);
session.getUserRegistry().put(path, node);
}
} catch (RegistryException e) {
String msg = "failed to remove the property " + this;
log.debug(msg);
throw new RepositoryException(msg, e);
}
}
private String getNodePath() throws RepositoryException {
if(isResource) {
try {
return session.getUserRegistry().get(path).getParentPath();
} catch (RegistryException e) {
throw new RepositoryException("Registry level Exception occurred, cannot " +
"obtain parent path of " + path);
}
} else {
return path;
}
}
private void persistNewPropertyValue(String type, Object value) throws RepositoryException {
Resource property;
try {
if (isResource) {
property = session.getUserRegistry().get(path);
} else {
property = session.getUserRegistry().get(path);
}
if (type.equals("value")) {
property.setContent(((Value) value).getString());
} else if (type.equals("string")) {
property.setProperty(name,value.toString());
} else if (type.equals("is")) {
property.setContentStream((InputStream)value);
} else if (type.equals("long")) {
property.setContent(String.valueOf(((Long) value).longValue()));
} else if (type.equals("double")) {
property.setContent(String.valueOf(((Double) value).doubleValue()));
} else if (type.equals("big_d")) {
property.setContent(((BigDecimal)value).toString());
} else if (type.equals("calendar")) {
property.setContent(String.valueOf(((Calendar) value).getTimeInMillis()));
} else if (type.equals("boolean")) {
property.setContent(String.valueOf(value.toString()));
}
session.getUserRegistry().put(path,property);
} catch (RegistryException e) {
throw new RepositoryException("Registry level exception occurred while " +
"setting value for " + path + e.getMessage());
} catch (ValueFormatException e) {
throw new ValueFormatException(e.getMessage());
} catch (RepositoryException e) {
throw new RepositoryException(e.getMessage());
}
}
private void setValuesToProperty(Value[] values) throws RepositoryException {
Resource resource = null;
try {
resource = session.getUserRegistry().get(path);
List<String> properties = new ArrayList<String>();
if (values != null) {
for (Value val : values) {
if (val != null) {
properties.add(val.getString());
}
}
resource.setProperty(name, properties);
}
session.getUserRegistry().put(path, resource);
} catch (RegistryException e) {
throw new RepositoryException("Registry level exception occurred" +
" while setting values[] for " + path);
}
}
}