blob: 706a28da5c523b3f28603d0fa4ffe73353486162 [file] [log] [blame]
/*
* 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.usergrid.persistence;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.usergrid.persistence.annotations.EntityProperty;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import static org.apache.usergrid.persistence.Schema.PROPERTY_NAME;
//import org.codehaus.jackson.annotate.JsonAnyGetter;
//import org.codehaus.jackson.annotate.JsonAnySetter;
//import org.codehaus.jackson.annotate.JsonIgnore;
//import org.codehaus.jackson.map.annotate.JsonSerialize;
//import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
/**
* The abstract superclass implementation of the Entity interface.
*
* @author edanuff
*/
@XmlRootElement
public abstract class AbstractEntity implements Entity {
protected UUID uuid;
protected Long created;
protected Long modified;
protected Map<String, Object> dynamic_properties = new TreeMap<String, Object>( String.CASE_INSENSITIVE_ORDER );
protected Map<String, Set<Object>> dynamic_sets = new TreeMap<String, Set<Object>>( String.CASE_INSENSITIVE_ORDER );
@Override
@EntityProperty(required = true, mutable = false, basic = true, indexed = false)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public UUID getUuid() {
return uuid;
}
@Override
public void setUuid( UUID uuid ) {
this.uuid = uuid;
}
@Override
@EntityProperty(required = true, mutable = false, basic = true, indexed = false)
public String getType() {
return Schema.getDefaultSchema().getEntityType( this.getClass() );
}
@Override
public void setType( String type ) {
}
@Override
@EntityProperty(indexed = true, required = true, mutable = false)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public Long getCreated() {
return created;
}
@Override
public void setCreated( Long created ) {
if ( created == null ) {
created = System.currentTimeMillis();
}
this.created = created;
}
@Override
@EntityProperty(indexed = true, required = true, mutable = true)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public Long getModified() {
return modified;
}
@Override
public void setModified( Long modified ) {
if ( modified == null ) {
modified = System.currentTimeMillis();
}
this.modified = modified;
}
@Override
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public String getName() {
Object value = getProperty( PROPERTY_NAME );
if ( value instanceof UUID ) {
// fixes existing data that uses UUID in USERGRID-2099
return value.toString();
}
return ( String ) value;
}
@Override
@JsonIgnore
public Map<String, Object> getProperties() {
return Schema.getDefaultSchema().getEntityProperties( this );
}
@Override
public final Object getProperty( String propertyName ) {
return Schema.getDefaultSchema().getEntityProperty( this, propertyName );
}
@Override
public final void setProperty( String propertyName, Object propertyValue ) {
Schema.getDefaultSchema().setEntityProperty( this, propertyName, propertyValue );
}
@Override
public void setProperties( Map<String, Object> properties ) {
dynamic_properties = new TreeMap<String, Object>( String.CASE_INSENSITIVE_ORDER );
addProperties( properties );
}
@Override
public void addProperties( Map<String, Object> properties ) {
if ( properties == null ) {
return;
}
for ( Entry<String, Object> entry : properties.entrySet() ) {
setProperty( entry.getKey(), entry.getValue() );
}
}
@Override
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public Object getMetadata( String key ) {
return getDataset( "metadata", key );
}
@Override
public void setMetadata( String key, Object value ) {
setDataset( "metadata", key, value );
}
@Override
public void mergeMetadata( Map<String, Object> new_metadata ) {
mergeDataset( "metadata", new_metadata );
}
@Override
public void clearMetadata() {
clearDataset( "metadata" );
}
public <T> T getDataset( String property, String key ) {
Object md = dynamic_properties.get( property );
if ( md == null ) {
return null;
}
if ( !( md instanceof Map<?, ?> ) ) {
return null;
}
@SuppressWarnings("unchecked") Map<String, T> metadata = ( Map<String, T> ) md;
return metadata.get( key );
}
public <T> void setDataset( String property, String key, T value ) {
if ( key == null ) {
return;
}
Object md = dynamic_properties.get( property );
if ( !( md instanceof Map<?, ?> ) ) {
md = new HashMap<String, T>();
dynamic_properties.put( property, md );
}
@SuppressWarnings("unchecked") Map<String, T> metadata = ( Map<String, T> ) md;
metadata.put( key, value );
}
public <T> void mergeDataset( String property, Map<String, T> new_metadata ) {
Object md = dynamic_properties.get( property );
if ( !( md instanceof Map<?, ?> ) ) {
md = new HashMap<String, T>();
dynamic_properties.put( property, md );
}
@SuppressWarnings("unchecked") Map<String, T> metadata = ( Map<String, T> ) md;
metadata.putAll( new_metadata );
}
public void clearDataset( String property ) {
dynamic_properties.remove( property );
}
@Override
public List<Entity> getCollections( String key ) {
return getDataset( "collections", key );
}
@Override
public void setCollections( String key, List<Entity> results ) {
setDataset( "collections", key, results );
}
@Override
public List<Entity> getConnections( String key ) {
return getDataset( "connections", key );
}
@Override
public void setConnections( String key, List<Entity> results ) {
setDataset( "connections", key, results );
}
@Override
public String toString() {
return "Entity(" + getProperties() + ")";
}
@Override
@JsonAnySetter
public void setDynamicProperty( String key, Object value ) {
if (value == null || value.equals("")) {
if (dynamic_properties.containsKey(key)) {
dynamic_properties.remove(key);
}
} else {
dynamic_properties.put(key, value);
}
}
@Override
@JsonAnyGetter
public Map<String, Object> getDynamicProperties() {
return dynamic_properties;
}
@Override
public final int compareTo( Entity o ) {
if ( o == null ) {
return 1;
}
try {
long t1 = getUuid().timestamp();
long t2 = o.getUuid().timestamp();
return ( t1 < t2 ) ? -1 : ( t1 == t2 ) ? 0 : 1;
}
catch ( UnsupportedOperationException e ) {
}
return getUuid().compareTo( o.getUuid() );
}
@Override
public Entity toTypedEntity() {
Entity entity = EntityFactory.newEntity( getUuid(), getType() );
entity.setProperties( getProperties() );
return entity;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ( ( uuid == null ) ? 0 : uuid.hashCode() );
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals( Object obj ) {
if ( this == obj ) {
return true;
}
if ( obj == null ) {
return false;
}
if ( getClass() != obj.getClass() ) {
return false;
}
AbstractEntity other = ( AbstractEntity ) obj;
if ( uuid == null ) {
if ( other.uuid != null ) {
return false;
}
}
else if ( !uuid.equals( other.uuid ) ) {
return false;
}
return true;
}
}