Index: /Dev/branches/jos-branch/server/classes/Model.php
===================================================================
--- /Dev/branches/jos-branch/server/classes/Model.php	(revision 314)
+++ /Dev/branches/jos-branch/server/classes/Model.php	(revision 315)
@@ -59,10 +59,24 @@
      * per type, because the result is cached.
      */
-    protected abstract static function createFIELDS();
+	protected abstract static function createFIELDS();
+
+	/**
+	 * Provides the modifiable fields of this object, throws an exception otherwise.
+	 * Needs to be implemented by every class to specify what fields are modifiable
+	 * in each state.
+	 */
+	protected abstract function getModifiableFields();
+
+	/**
+	 * Returns whether the object is removable in its current state. Needs to be 
+	 * implemented by every class.
+	 */
+//	protected abstract function isRemovable();
+
 
     // instance fields
 
     private $uid = null;
-    private $uri = null;
+	private $uri = null;
     private $values = array();
 
@@ -77,5 +91,5 @@
     public function getType() {
         return static::TYPE();
-    }
+	}
 
     // PHP magic functions to expose values
@@ -97,5 +111,5 @@
             throw new Exception("Field " . $name . " not defined on " . self::TYPE());
         }
-    }
+	}
 
     private function get_field($name) {
@@ -119,10 +133,10 @@
 
     public function __set($name, $value) {
-        self::ensure_field($name);
+		self::ensure_field($name);
         $this->values[$name] = $value;
     }
 
     public function __unset($name) {
-        unset($this->values[$name]);
+	    unset($this->values[$name]);
     }
 
@@ -162,11 +176,23 @@
     }
 
-    protected function evaluate() {
+	protected function evaluate() {
+		$realClass = self::TYPE();
+		$oldResults = $realClass::get(array("uid" => $this->uid));
         foreach (static::FIELDS() as $name => $field) {
             if ($field->required()
-                    && (!is_set($this->values[$name])
+                    && (!isset($this->values[$name])
                     || ( $field->multiple() && empty($this->values[$name]) ) )) {
                 throw new Exception("Required field $name not found.");
-            }
+			}
+			if (!empty($oldResults) 
+				&& $this->values[$name] != $oldResults[0]->values[$name] 
+				&& !in_array($name, $this->getModifiableFields()))	
+			{
+				$state = "";
+				if(isset($this->values[$state]))
+					$state = $this->values[$state];
+				throw new Exception("Field " . $name . " is not modifiable on type " . $realClass . " in current state " . $state);
+			}
+
         }
     }
@@ -174,9 +200,9 @@
     public function save() {
         $this->evaluate();
-
+		
         $model = self::get_model();
 
         // create new resource and remove old saved resource
-        $resource = new Resource($this->uri);
+		$resource = new Resource($this->uri);
         $model->subtract($model->find($resource, null, null));
 
@@ -259,5 +285,5 @@
                     }
                 }
-                $info = self::resourceUriToTypeAndUid($uri);
+				$info = self::resourceUriToTypeAndUid($uri);
                 $objects[] = new $realClass($info['uid'], $values);
             }
@@ -423,4 +449,21 @@
 }
 
+class RdfInteger implements RdfType {
+	static function save($model, $resource, $name, $value) {
+		$model->add(new Statement($resource, new Resource(RDfObject::PREDICATES_NS . $name),
+			new Literal($value)));
+	}
+	static function load($value) {
+		return (int) $value->label;
+	}
+	static function predicate($name, $value) {
+		return 'str(?' . $name .') = "' . $value . '"';
+	}
+}
+
+function RdfInteger() {
+	return new RdfInteger();
+}
+
 class RdfReference implements RdfType {
 
@@ -454,6 +497,9 @@
             'values' => RdfField(RdfString(), array(RdfField::MULTIPLE))
         );
-    }
-
+	}
+
+	protected function getModifiableFields() {
+		return array('question', 'values');
+	}
 }
 
@@ -467,6 +513,9 @@
             'answers' => RdfField(RdfReference(), array(RdfField::MULTIPLE))
         );
-    }
-
+	}
+
+	protected function getModifiableFields() {
+		return array('survey', 'respondent', 'answers');
+	}
 }
 
@@ -479,6 +528,9 @@
             'style' => RdfField(RdfString())
         );
-    }
-
+	}
+
+	protected function getModifiableFields() {
+		return array('title', 'description', 'style');
+	}
 }
 
@@ -493,4 +545,7 @@
         );
     }
+	protected function getModifiableFields() {
+		return array();
+	}
 
 }
@@ -508,4 +563,7 @@
         );
     }
+	protected function getModifiableFields() {
+		return array();
+	}
 
 }
@@ -521,4 +579,11 @@
         );
     }
+	protected function getModifiableFields() {
+		switch($this->getState())
+		{
+			case 0: return array('title', 'pipeline');
+			case 1: return array('title');
+		}
+	}
 
 }
@@ -539,4 +604,7 @@
         );
     }
+	protected function getModifiableFields() {
+		return array();
+	}
 
 }
@@ -552,4 +620,12 @@
         );
     }
+	protected function getModifiableFields() {
+		switch($this->getState())
+		{
+			case 0: return array('title', 'description', 'creator', 'questions');
+			case 1: return array('title', 'description', 'questions');
+			default: return array('title', 'description');
+		}
+	}
 
 }
@@ -567,4 +643,7 @@
         );
     }
+	protected function getModifiableFields() {
+		return array();
+	}
 
 }
@@ -579,4 +658,7 @@
         );
     }
+	protected function getModifiableFields() {
+		return array('passwordHash', 'passwordSalt');
+	}
 
 }
