1: <?php
2: /**
3: * Copyright 2012-2014 Rackspace US, Inc.
4: *
5: * Licensed under the Apache License, Version 2.0 (the "License");
6: * you may not use this file except in compliance with the License.
7: * You may obtain a copy of the License at
8: *
9: * http://www.apache.org/licenses/LICENSE-2.0
10: *
11: * Unless required by applicable law or agreed to in writing, software
12: * distributed under the License is distributed on an "AS IS" BASIS,
13: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14: * See the License for the specific language governing permissions and
15: * limitations under the License.
16: */
17:
18: namespace OpenCloud\Image\Resource\Schema;
19:
20: use OpenCloud\Image\Enum\OperationType;
21: use OpenCloud\Image\Enum\Schema as SchemaEnum;
22:
23: /**
24: * Class that represents a JSON schema document
25: *
26: * @package OpenCloud\Images\Resource\Schema
27: */
28: class Schema extends AbstractSchemaItem
29: {
30: /** @var string Name of schema */
31: protected $name;
32:
33: /** @var array Properties that this schema possesses */
34: protected $properties;
35:
36: /**
37: * If set, this determines the template that all additional (i.e. undefined) properties must adhere to
38: *
39: * @var null|Property
40: */
41: protected $additionalProperties;
42:
43: /** @var array Links for this schema */
44: protected $links;
45:
46: /**
47: * @param array $data
48: * @return Schema
49: */
50: public static function factory(array $data)
51: {
52: $schema = new self();
53:
54: $schema->setName(self::stockProperty($data, SchemaEnum::NAME));
55:
56: if (isset($data[SchemaEnum::LINKS])) {
57: $schema->setLinks($data[SchemaEnum::LINKS]);
58: }
59:
60: if (isset($data[SchemaEnum::PROPERTIES])) {
61: $schema->setProperties($data[SchemaEnum::PROPERTIES]);
62: }
63:
64: if (isset($data[SchemaEnum::ADDITIONAL_PROPERTIES])) {
65: $schema->setAdditionalProperties($data[SchemaEnum::ADDITIONAL_PROPERTIES]);
66: }
67:
68: return $schema;
69: }
70:
71: /**
72: * @param string $name
73: */
74: public function setName($name)
75: {
76: $this->name = $name;
77: }
78:
79: /**
80: * @return string
81: */
82: public function getName()
83: {
84: return $this->name;
85: }
86:
87: /**
88: * @param array $properties
89: */
90: public function setProperties(array $properties)
91: {
92: foreach ($properties as $name => $array) {
93: $array[SchemaEnum::NAME] = $name;
94: $this->properties[$name] = Property::factory($array);
95: }
96: }
97:
98: /**
99: * @return array
100: */
101: public function getProperties()
102: {
103: return $this->properties;
104: }
105:
106: /**
107: * @param array $properties
108: */
109: public function setAdditionalProperties(array $properties)
110: {
111: $this->additionalProperties = $properties;
112: }
113:
114: /**
115: * @return bool|Property
116: */
117: public function getAdditionalProperties()
118: {
119: if (!empty($this->additionalProperties)) {
120: return Property::factory($this->additionalProperties);
121: }
122:
123: return false;
124: }
125:
126: /**
127: * @param array $links
128: */
129: public function setLinks(array $links)
130: {
131: $this->links = $links;
132: }
133:
134: /**
135: * @return array
136: */
137: public function getLinks()
138: {
139: return $this->links;
140: }
141:
142: /**
143: * Check whether a property exists
144: *
145: * @param $property The name of the property
146: * @return bool
147: */
148: public function propertyExists($property)
149: {
150: return isset($this->properties[$property]);
151: }
152:
153: /**
154: * Retrieve a property
155: *
156: * @param $property The name of the property
157: * @return null|Property
158: */
159: public function getProperty($property)
160: {
161: return $this->propertyExists($property) ? $this->properties[$property] : null;
162: }
163:
164: /**
165: * Based on this schema, decide the most appropriate operation type for a given property
166: *
167: * @param Property $property The property being performed on
168: * @return string
169: */
170: public function decideOperationType(Property $property)
171: {
172: $name = $property->getName();
173:
174: return ($this->propertyExists($name)) ? OperationType::REPLACE : OperationType::ADD;
175: }
176:
177: /**
178: * Check whether an additional property is allowed and its type is valid
179: *
180: * @param $value The value trying to be set
181: * @return bool|Property
182: */
183: public function validateAdditionalProperty($value)
184: {
185: if ($property = $this->getAdditionalProperties()) {
186: $property->setValue($value);
187:
188: return ($property->validate() === true) ? $property : false;
189: }
190:
191: return false;
192: }
193: }
194: