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.
/*
* Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Codename One designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Codename One through http://www.codenameone.com/ if you
* need additional information or have any questions.
*/
package com.codename1.cloud;
import com.codename1.cloud.BindTarget;
import com.codename1.io.Externalizable;
import com.codename1.io.Util;
import com.codename1.ui.Component;
import com.codename1.ui.Container;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
/**
* A cloud object can be persisted to the cloud or locally
* it is a set of key/value pairs that can be either strings
* or numbers. There is a 512 character limit on string length!
* Notice: keys starting with CN1 are reserved for internal usage!
*
* @author Shai Almog
* @deprecated the cloud storage API is no longer supported, we recommend switching to a solution such as parse4cn1
*/
public final class CloudObject implements Externalizable {
/**
* Indicates the state of the current object, a new object never persisted
*/
public static final int STATUS_NEW = 0;
/**
* Indicates the state of the current object, an object that is in sync with the database as far as
* the client code is aware (the client code doesn't check!)
*/
public static final int STATUS_COMMITTED = 1;
/**
* Indicates the state of the current object, a locally modified object that wasn't committed yet
*/
public static final int STATUS_MODIFIED = 2;
/**
* Indicates the state of the current object, an object in the process of committing
*/
public static final int STATUS_COMMIT_IN_PROGRESS = 3;
/**
* Indicates the state of the current object, an object that is in the process of deletion
*/
public static final int STATUS_DELETE_IN_PROGRESS = 4;
/**
* Indicates the state of the current object, a deleted object
*/
public static final int STATUS_DELETED = 5;
/**
* Indicates the state of the current object, an object in the process of refresh
*/
public static final int STATUS_REFRESH_IN_PROGRESS = 6;
/**
* A world visible/modifiable object!
*/
public static final int ACCESS_PUBLIC = 1;
/**
* A world visible object! Can only be modified by its creator.
*/
public static final int ACCESS_PUBLIC_READ_ONLY = 2;
/**
* An application visible/modifiable object!
*/
public static final int ACCESS_APPLICATION = 3;
/**
* An application scope readable object! Can only be modified by its creator
*/
public static final int ACCESS_APPLICATION_READ_ONLY = 4;
/**
* An object that can only be viewed or modified by its creator
*/
public static final int ACCESS_PRIVATE = 5;
/**
* Changes to the bound property won't be reflected into the bound cloud object until commit binding is invoked
*/
public static final int BINDING_DEFERRED = 1;
/**
* Changes to the bound property will be reflected instantly into the cloud object
*/
public static final int BINDING_IMMEDIATE = 2;
/**
* Changes to the bound property will be reflected instantly into the cloud object and the object would
* be saved immediately (not committed!).
*/
public static final int BINDING_AUTO_SAVE = 3;
private static Hashtable custom = new Hashtable();
private Hashtable values = new Hashtable();
private Hashtable deferedValues;
private String cloudId;
private long lastModified;
private int status;
private boolean owner = true;
private int accessPermissions = ACCESS_PRIVATE;
/**
* Default constructor for externalization purposes only!
*/
public CloudObject() {}
/**
* Constructor
* @param type the type of the object
*/
public CloudObject(String type) {
values.put(CloudStorage.TYPE_FIELD, type);
}
/**
* Create an object with different permissions settings
*
* @param type the type of the object
* @param permissions one of the ACCESS_* values
*/
public CloudObject(String type, int permissions) {
accessPermissions = permissions;
values.put(CloudStorage.TYPE_FIELD, type);
}
CloudObject(int permissions) {
accessPermissions = permissions;
}
/**
* Returns one of the status constants in this class
* @return the status of the object against the cloud
*/
public int getStatus() {
return status;
}
void setStatus(int s) {
status = s;
}
void setValues(Hashtable values) {
this.values = values;
}
Hashtable getValues() {
return values;
}
/**
* Set the type of the object
* @param type the type of the field
*/
public void setType(String type) {
setString(CloudStorage.TYPE_FIELD, type);
}
/**
* Returns the type of the object
* @return the type of the object
*/
public String getType() {
return getString(CloudStorage.TYPE_FIELD);
}
/**
* Only indexed values can be queried and sorted
* @param index the index which must be a value between 1 and 10.
* @param value the value for the given index
*/
public void setIndexString(int index, String value) {
if(index > 10 || index < 1) {
throw new IllegalArgumentException("Invalid index: " + index);
}
setString(CloudStorage.INDEX_FIELD + index, value);
}
/**
* Returns the index value for the given index number
*
* @param index the index number
* @return the value of this entry for that index as a String
*/
public String getIndexString(int index) {
return getString(CloudStorage.INDEX_FIELD + index);
}
/**
* Only indexed values can be queried and sorted
* @param index the index which must be a value between 1 and 10.
* @param value the value for the given index
*/
public void setIndexLong(int index, long value) {
if(index > 10 || index < 1) {
throw new IllegalArgumentException("Invalid index: " + index);
}
setLong(CloudStorage.INDEX_FIELD + index, value);
}
/**
* Returns the index value for the given index number
*
* @param index the index number
* @return the value of this entry for that index as a Long value
*/
public Long getIndexLong(int index) {
return getLong(CloudStorage.INDEX_FIELD + index);
}
/**
* Only indexed values can be queried and sorted
* @param index the index which must be a value between 1 and 10.
* @param value the value for the given index
*/
public void setIndexDouble(int index, double value) {
if(index > 10 || index < 1) {
throw new IllegalArgumentException("Invalid index: " + index);
}
setDouble(CloudStorage.INDEX_FIELD + index, value);
}
/**
* Returns the index value for the given index number
*
* @param index the index number
* @return the value of this entry for that index as a Double value
*/
public Double getIndexDouble(int index) {
return getDouble(CloudStorage.INDEX_FIELD + index);
}
/**
* Returns true if this object is owned by me or is world writeable
* @return ownership status
*/
public boolean isOwner() {
return owner;
}
/**
* The object id is a unique key that allows you to find an object that was persisted in the
* store (a primary key). When it is null the object is effectively unsynchronized!
* @return the object id or null for an object that isn't fully persisted yet
*/
public String getCloudId() {
return cloudId;
}
void setCloudId(String cloudId) {
this.cloudId = cloudId;
}
/**
* Indicates the last modification date for the object
* @return the last modification date
*/
public long getLastModified() {
return lastModified;
}
void setLastModified(long lastModified) {
this.lastModified = lastModified;
}
/**
* Allows us to extract an object from the cloud object without knowing its type in advance
* or whether it exists
* @param key the key for the object
* @return the value of the object
*/
public Object getObject(String key) {
Object o = values.get(key);
if(o == null) {
CustomProperty cp = custom.get(key);
if(cp != null) {
return cp.propertyValue(this, key);
}
}
return o;
}
/**
* Install a custom property on the given property name
*
* @param key the key on which to install the custom property
* @param cp the custom property implementation
*/
public static void setCustomProperty(String key, CustomProperty cp) {
if(cp == null) {
custom.remove(key);
} else {
custom.put(key, cp);
}
}
/**
* Sets a value that can be no more than 512 characters
*
* @param key the key for the given value
* @param value the value
*/
public void setString(String key, String value) {
if(!owner) {
throw new RuntimeException("Read only object, you are not the owner");
}
if(value == null) {
values.remove(key);
return;
}
if(value.length() > 512) {
throw new IllegalArgumentException("String too long!");
}
status = STATUS_MODIFIED;
values.put(key, value);
}
/**
* Returns the value for the given key
* @param key the key
* @return a string value
*/
public String getString(String key) {
return (String)getObject(key);
}
/**
* Delete an entry within the object
* @param key the key to remove from the object
*/
public void remove(String key) {
values.remove(key);
}
/**
* Sets a value
*
* @param key the key for the given value
* @param value the value
*/
public void setLong(String key, long value) {
if(!owner) {
throw new RuntimeException("Read only object, you are not the owner");
}
status = STATUS_MODIFIED;
values.put(key, new Long(value));
}
/**
* Sets a value
*
* @param key the key for the given value
* @param value the value
*/
public void setLong(String key, Long value) {
if(!owner) {
throw new RuntimeException("Read only object, you are not the owner");
}
status = STATUS_MODIFIED;
values.put(key, value);
}
/**
* Returns the value for the given key
* @param key the key
* @return a long value
*/
public Long getLong(String key) {
Object o = getObject(key);
if(o instanceof Integer) {
return new Long(((Integer)o).intValue());
}
return (Long)o;
}
/**
* Sets a value
*
* @param key the key for the given value
* @param value the value
*/
public void setInteger(String key, int value) {
if(!owner) {
throw new RuntimeException("Read only object, you are not the owner");
}
status = STATUS_MODIFIED;
values.put(key, new Integer(value));
}
/**
* Sets a value
*
* @param key the key for the given value
* @param value the value
*/
public void setInteger(String key, Integer value) {
if(!owner) {
throw new RuntimeException("Read only object, you are not the owner");
}
status = STATUS_MODIFIED;
values.put(key, value);
}
/**
* Returns the value for the given key
* @param key the key
* @return a value
*/
public Integer getInteger(String key) {
Object o = getObject(key);
if(o instanceof Long) {
return new Integer((int)((Long)o).longValue());
}
return (Integer)o;
}
/**
* Sets a value
*
* @param key the key for the given value
* @param value the value
*/
public void setDouble(String key, double value) {
if(!owner) {
throw new RuntimeException("Read only object, you are not the owner");
}
status = STATUS_MODIFIED;
values.put(key, new Double(value));
}
/**
* Sets a value
*
* @param key the key for the given value
* @param value the value
*/
public void setDouble(String key, Double value) {
if(!owner) {
throw new RuntimeException("Read only object, you are not the owner");
}
status = STATUS_MODIFIED;
values.put(key, value);
}
/**
* Returns the value for the given key
* @param key the key
* @return a value
*/
public Double getDouble(String key) {
return (Double)getObject(key);
}
/**
* Sets a value
*
* @param key the key for the given value
* @param value the value
*/
public void setFloat(String key, float value) {
if(!owner) {
throw new RuntimeException("Read only object, you are not the owner");
}
status = STATUS_MODIFIED;
values.put(key, new Float(value));
}
/**
* Sets a value
*
* @param key the key for the given value
* @param value the value
*/
public void setFloat(String key, Float value) {
if(!owner) {
throw new RuntimeException("Read only object, you are not the owner");
}
status = STATUS_MODIFIED;
values.put(key, value);
}
/**
* Returns the value for the given key
* @param key the key
* @return a value
*/
public Float getFloat(String key) {
Object o = getObject(key);
if(o instanceof Double) {
return new Float(((Double)o).floatValue());
}
return (Float)o;
}
/**
* Sets a value
*
* @param key the key for the given value
* @param value the value
*/
public void setBoolean(String key, boolean value) {
if(!owner) {
throw new RuntimeException("Read only object, you are not the owner");
}
status = STATUS_MODIFIED;
values.put(key, new Boolean(value));
}
/**
* Sets a value
*
* @param key the key for the given value
* @param value the value
*/
public void setBoolean(String key, Boolean value) {
if(!owner) {
throw new RuntimeException("Read only object, you are not the owner");
}
status = STATUS_MODIFIED;
values.put(key, value);
}
/**
* Returns the value for the given key
* @param key the key
* @return a value
*/
public Boolean getBoolean(String key) {
return (Boolean)getObject(key);
}
/**
* {@inheritDoc}
*/
public int getVersion() {
return 1;
}
/**
* {@inheritDoc}
*/
public void externalize(DataOutputStream out) throws IOException {
Util.writeUTF(cloudId, out);
out.writeBoolean(owner);
out.writeByte(getAccessPermissions());
out.writeLong(lastModified);
out.writeInt(status);
Util.writeObject(values, out);
}
public String getObjectId() {
return "CloudObject";
}
/**
* {@inheritDoc}
*/
public void internalize(int version, DataInputStream in) throws IOException {
cloudId = Util.readUTF(in);
owner = in.readBoolean();
accessPermissions = in.readByte();
lastModified = in.readLong();
status = in.readInt();
values = (Hashtable)Util.readObject(in);
}
/**
* The access permissions for an object can only be changed for an object in which
* the current user is the owner
* @return the accessPermissions
*/
public int getAccessPermissions() {
return accessPermissions;
}
/**
* {@inheritDoc}
*/
public boolean equals(Object o) {
if(!(o instanceof CloudObject)) {
return false;
}
CloudObject cl = (CloudObject)o;
if(cloudId == null && cl.cloudId == null) {
return values.equals(cl.values);
}
if(cloudId == null || cl.cloudId == null) {
return false;
}
return cloudId.equals(cl.cloudId);
}
/**
* {@inheritDoc}
*/
public int hashCode() {
if(cloudId != null) {
return cloudId.hashCode();
}
return 0;
}
/**
* Binds a UI tree to the cloud object so its values automatically update in the cloud object
*
* @param ui the component tree to bind
* @param defer bind settings whether to defer the binding which requires developers to explicitly commit
* the binding to perform the changes
* @param objectLead if set to true the UI property is initialized from values in the CloudObject, if false
* the cloud object property is initialized from the UI
*/
public void bindTree(Container ui, int defer, boolean objectLead) {
int componentCount = ui.getComponentCount();
for(int iter = 0 ; iter < componentCount ; iter++) {
Component c = ui.getComponentAt(iter);
if(c instanceof Container) {
bindTree((Container)c, defer, objectLead);
continue;
}
String bind = c.getCloudBoundProperty();
if(bind != null && bind.length() > 0) {
String attributeName = c.getCloudDestinationProperty();
if(attributeName != null) {
bindProperty(c, bind, attributeName, defer, objectLead);
}
}
}
}
/**
* Clears the binding to this component tree
* @param ui the container whose children might be bound
*/
public void unbindTree(Container ui) {
int componentCount = ui.getComponentCount();
for(int iter = 0 ; iter < componentCount ; iter++) {
Component c = ui.getComponentAt(iter);
if(c instanceof Container) {
unbindTree((Container)c);
continue;
}
String bind = c.getCloudBoundProperty();
if(bind != null && bind.length() > 0) {
String attributeName = c.getCloudDestinationProperty();
if(attributeName != null) {
unbindProperty(c, bind);
}
}
}
}
/**
* Binds a property value within the given component to this cloud object, this means that
* when the component changes the cloud object changes unless deferred. If the defer flag is
* false all changes are stored in a temporary location and only "committed" once commitBindings()
* is invoked.
* @param cmp the component to bind
* @param propertyName the name of the property in the bound component
* @param attributeName the key within the cloud object
* @param defer bind settings whether to defer the binding which requires developers to explicitly commit
* the binding to perform the changes
* @param objectLead if set to true the UI property is initialized from values in the CloudObject, if false
* the cloud object property is initialized from the UI
*/
public void bindProperty(Component cmp, final String propertyName, final String attributeName, final int defer, boolean objectLead) {
if(objectLead) {
Object val = values.get(attributeName);
Object cmpVal = cmp.getBoundPropertyValue(propertyName);
if(val == null) {
if(cmpVal != null) {
cmp.setBoundPropertyValue(propertyName, null);
}
} else {
if(cmpVal == null || !(val.equals(cmpVal))) {
cmp.setBoundPropertyValue(propertyName, val);
}
}
} else {
Object val = values.get(attributeName);
Object cmpVal = cmp.getBoundPropertyValue(propertyName);
if(cmpVal == null) {
if(val != null) {
values.remove(attributeName);
status = STATUS_MODIFIED;
}
} else {
if(val == null || !(val.equals(cmpVal))) {
values.put(attributeName, cmpVal);
status = STATUS_MODIFIED;
}
}
}
BindTarget target = new BindTarget() {
public void propertyChanged(Component source, String propertyName, Object oldValue, Object newValue) {
switch(defer) {
case BINDING_DEFERRED:
if(deferedValues == null) {
deferedValues = new Hashtable();
}
deferedValues.put(attributeName, newValue);
break;
case BINDING_IMMEDIATE:
values.put(attributeName, newValue);
status = STATUS_MODIFIED;
break;
case BINDING_AUTO_SAVE:
values.put(attributeName, newValue);
status = STATUS_MODIFIED;
CloudStorage.getInstance().save(CloudObject.this);
break;
}
}
};
cmp.bindProperty(propertyName, target);
cmp.putClientProperty("CN1Bind" + propertyName, target);
}
/**
* Releases the binding for the specific property name
* @param cmp the component
* @param propertyName the name of the property
*/
public void unbindProperty(Component cmp, String propertyName) {
BindTarget t = (BindTarget)cmp.getClientProperty("CN1Bind" + propertyName);
cmp.unbindProperty(propertyName, t);;
}
/**
* If deferred changes exist this method applies these changes to the data
*/
public void commitBinding() {
if(deferedValues != null && deferedValues.size() > 0) {
Enumeration en = deferedValues.keys();
while(en.hasMoreElements()) {
Object k = en.nextElement();
values.put(k, deferedValues.get(k));
}
deferedValues = null;
}
}
/**
* If deferred changes exist this method discards such values
*/
public void cancelBinding() {
deferedValues = null;
}
}