http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Artifact.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Artifact.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Artifact.java deleted file mode 100644 index 697a3ba..0000000 --- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Artifact.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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 io.brooklyn.camp.spi.pdp; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.builder.ToStringBuilder; - -import brooklyn.util.collections.MutableMap; -import brooklyn.util.yaml.Yamls; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; - -public class Artifact { - - String name; - String description; - String artifactType; - - ArtifactContent content; - List<ArtifactRequirement> requirements; - - Map<String,Object> customAttributes; - - @SuppressWarnings("unchecked") - public static Artifact of(Map<String, Object> artifact) { - Map<String,Object> fields = MutableMap.copyOf(artifact); - - Artifact result = new Artifact(); - result.name = (String) fields.remove("name"); - result.description = (String) fields.remove("description"); - result.artifactType = (String) (String) Yamls.removeMultinameAttribute(fields, "artifactType", "type"); - - result.content = ArtifactContent.of( fields.remove("content") ); - - result.requirements = new ArrayList<ArtifactRequirement>(); - Object reqs = fields.remove("requirements"); - if (reqs instanceof Iterable) { - for (Object req: (Iterable<Object>)reqs) { - if (req instanceof Map) { - result.requirements.add(ArtifactRequirement.of((Map<String,Object>) req)); - } else { - throw new IllegalArgumentException("requirement should be a map, not "+req.getClass()); - } - } - } else if (reqs!=null) { - // TODO "map" short form - throw new IllegalArgumentException("artifacts body should be iterable, not "+reqs.getClass()); - } - - result.customAttributes = fields; - - return result; - } - - public String getName() { - return name; - } - public String getDescription() { - return description; - } - public String getArtifactType() { - return artifactType; - } - public ArtifactContent getContent() { - return content; - } - public List<ArtifactRequirement> getRequirements() { - return ImmutableList.copyOf(requirements); - } - public Map<String, Object> getCustomAttributes() { - return ImmutableMap.copyOf(customAttributes); - } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this); - } - -}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ArtifactContent.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ArtifactContent.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ArtifactContent.java deleted file mode 100644 index e6d1b05..0000000 --- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ArtifactContent.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 io.brooklyn.camp.spi.pdp; - -import java.util.Map; - -import org.apache.commons.lang3.builder.ToStringBuilder; - -import brooklyn.util.collections.MutableMap; - -import com.google.common.collect.ImmutableMap; - -public class ArtifactContent { - - String href; - Map<String,Object> customAttributes; - - public static ArtifactContent of(Object spec) { - if (spec==null) return null; - - ArtifactContent result = new ArtifactContent(); - if (spec instanceof String) { - result.href = (String)spec; - } else if (spec instanceof Map) { - @SuppressWarnings("unchecked") - Map<String,Object> attrs = MutableMap.copyOf( (Map<String,Object>) spec ); - result.href = (String) attrs.remove("href"); - result.customAttributes = attrs; - } else { - throw new IllegalArgumentException("artifact content should be map or string, not "+spec.getClass()); - } - - return result; - } - - public String getHref() { - return href; - } - - public Map<String, Object> getCustomAttributes() { - return ImmutableMap.copyOf(customAttributes); - } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ArtifactRequirement.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ArtifactRequirement.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ArtifactRequirement.java deleted file mode 100644 index da9936a..0000000 --- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ArtifactRequirement.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 io.brooklyn.camp.spi.pdp; - -import java.util.Map; - -import org.apache.commons.lang3.builder.ToStringBuilder; - -import brooklyn.util.collections.MutableMap; -import brooklyn.util.yaml.Yamls; - -import com.google.common.collect.ImmutableMap; - -public class ArtifactRequirement { - - String name; - String description; - String requirementType; - - Map<String,Object> customAttributes; - - public static ArtifactRequirement of(Map<String, Object> req) { - Map<String,Object> attrs = MutableMap.copyOf(req); - - ArtifactRequirement result = new ArtifactRequirement(); - result.name = (String) attrs.remove("name"); - result.description = (String) attrs.remove("description"); - result.requirementType = (String) (String) Yamls.removeMultinameAttribute(attrs, "requirementType", "type"); - - // TODO fulfillment - - result.customAttributes = attrs; - - return result; - } - - public String getName() { - return name; - } - public String getDescription() { - return description; - } - public String getRequirementType() { - return requirementType; - } - - public Map<String, Object> getCustomAttributes() { - return ImmutableMap.copyOf(customAttributes); - } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/AssemblyTemplateConstructor.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/AssemblyTemplateConstructor.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/AssemblyTemplateConstructor.java deleted file mode 100644 index c535754..0000000 --- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/AssemblyTemplateConstructor.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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 io.brooklyn.camp.spi.pdp; - -import java.util.Map; - -import io.brooklyn.camp.CampPlatform; -import io.brooklyn.camp.spi.ApplicationComponentTemplate; -import io.brooklyn.camp.spi.AssemblyTemplate; -import io.brooklyn.camp.spi.AssemblyTemplate.Builder; -import io.brooklyn.camp.spi.PlatformComponentTemplate; -import io.brooklyn.camp.spi.PlatformTransaction; -import io.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator; - -public class AssemblyTemplateConstructor { - - private final Builder<? extends AssemblyTemplate> builder; - private final CampPlatform campPlatform; - protected PlatformTransaction transaction; - - public AssemblyTemplateConstructor(CampPlatform campPlatform) { - this.campPlatform = campPlatform; - this.builder = AssemblyTemplate.builder(); - this.transaction = this.campPlatform.transaction(); - } - - /** records all the templates to the underlying platform */ - public AssemblyTemplate commit() { - checkState(); - AssemblyTemplate at = builder.build(); - transaction.add(at).commit(); - transaction = null; - return at; - } - - public void name(String name) { - checkState(); - builder.name(name); - } - - public void description(String description) { - checkState(); - builder.description(description); - } - - - public void sourceCode(String sourceCode) { - checkState(); - builder.sourceCode(sourceCode); - } - - public void addCustomAttributes(Map<String, Object> attrs) { - for (Map.Entry<String, Object> attr : attrs.entrySet()) - builder.customAttribute(attr.getKey(), attr.getValue()); - } - - public void instantiator(Class<? extends AssemblyTemplateInstantiator> instantiator) { - checkState(); - builder.instantiator(instantiator); - } - - public Class<? extends AssemblyTemplateInstantiator> getInstantiator() { - checkState(); - return builder.peek().getInstantiator(); - } - - public void add(ApplicationComponentTemplate act) { - checkState(); - builder.add(act); - transaction.add(act); - } - - public void add(PlatformComponentTemplate pct) { - checkState(); - builder.add(pct); - transaction.add(pct); - } - - protected void checkState() { - if (transaction == null) - throw new IllegalStateException("transaction already committed"); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/DeploymentPlan.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/DeploymentPlan.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/DeploymentPlan.java deleted file mode 100644 index df2d895..0000000 --- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/DeploymentPlan.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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 io.brooklyn.camp.spi.pdp; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.builder.ToStringBuilder; - -import brooklyn.util.collections.MutableMap; -import brooklyn.util.guava.Maybe; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; - -public class DeploymentPlan { - - String name; - String origin; - String description; - String sourceCode; - - List<Artifact> artifacts; - List<Service> services; - Map<String,Object> customAttributes; - - @Deprecated /** @deprecated since 0.7.0; supply source code also, for reference */ - public static DeploymentPlan of(Map<String,Object> root) { - return of(root, null); - } - @SuppressWarnings("unchecked") - public static DeploymentPlan of(Map<String,Object> root, String optionalSourceCode) { - Map<String,Object> attrs = MutableMap.copyOf(root); - - DeploymentPlan result = new DeploymentPlan(); - result.name = (String) attrs.remove("name"); - result.description = (String) attrs.remove("description"); - result.origin = (String) attrs.remove("origin"); - result.sourceCode = optionalSourceCode; - // TODO version - - result.services = new ArrayList<Service>(); - Object services = attrs.remove("services"); - if (services instanceof Iterable) { - for (Object service: (Iterable<Object>)services) { - if (service instanceof Map) { - result.services.add(Service.of((Map<String,Object>) service)); - } else { - throw new IllegalArgumentException("service should be map, not "+service.getClass()); - } - } - } else if (services!=null) { - // TODO "map" short form - throw new IllegalArgumentException("artifacts body should be iterable, not "+services.getClass()); - } - - result.artifacts = new ArrayList<Artifact>(); - Object artifacts = attrs.remove("artifacts"); - if (artifacts instanceof Iterable) { - for (Object artifact: (Iterable<Object>)artifacts) { - if (artifact instanceof Map) { - result.artifacts.add(Artifact.of((Map<String,Object>) artifact)); - } else { - throw new IllegalArgumentException("artifact should be map, not "+artifact.getClass()); - } - } - } else if (artifacts!=null) { - // TODO "map" short form - throw new IllegalArgumentException("artifacts body should be iterable, not "+artifacts.getClass()); - } - - result.customAttributes = attrs; - - return result; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - public String getOrigin() { - return origin; - } - - public String getSourceCode() { - return sourceCode; - } - - public List<Artifact> getArtifacts() { - return ImmutableList.copyOf(artifacts); - } - - public List<Service> getServices() { - return ImmutableList.copyOf(services); - } - - public Map<String, Object> getCustomAttributes() { - return ImmutableMap.copyOf(customAttributes); - } - - /** - * Returns a present {@link Maybe} of the custom attribute with the given name if the attribute is - * non-null and is an instance of the given type. Otherwise returns absent. - * <p/> - * Does not remove the attribute from the custom attribute map. - */ - @SuppressWarnings("unchecked") - public <T> Maybe<T> getCustomAttribute(String attributeName, Class<T> type, boolean throwIfTypeMismatch) { - Object attribute = customAttributes.get(attributeName); - if (attribute == null) { - return Maybe.absent("Custom attributes does not contain " + attributeName); - } else if (!type.isAssignableFrom(attribute.getClass())) { - String message = "Custom attribute " + attributeName + " is not of expected type: " + - "expected=" + type.getName() + " actual=" + attribute.getClass().getName(); - if (throwIfTypeMismatch) { - throw new IllegalArgumentException(message); - } - return Maybe.absent(message); - } else { - return Maybe.of((T) attribute); - } - } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Service.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Service.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Service.java deleted file mode 100644 index dbd55b3..0000000 --- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Service.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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 io.brooklyn.camp.spi.pdp; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.builder.ToStringBuilder; - -import brooklyn.util.collections.MutableMap; -import brooklyn.util.yaml.Yamls; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; - -public class Service { - - String name; - String description; - String serviceType; - - List<ServiceCharacteristic> characteristics; - - Map<String,Object> customAttributes; - - @SuppressWarnings("unchecked") - public static Service of(Map<String, Object> service) { - Map<String,Object> fields = MutableMap.copyOf(service); - - Service result = new Service(); - result.name = (String) fields.remove("name"); - result.description = (String) fields.remove("description"); - // FIXME _type needed in lots of places - result.serviceType = (String) Yamls.removeMultinameAttribute(fields, "service_type", "serviceType", "type"); - - result.characteristics = new ArrayList<ServiceCharacteristic>(); - Object chars = fields.remove("characteristics"); - if (chars instanceof Iterable) { - for (Object req: (Iterable<Object>)chars) { - if (req instanceof Map) { - result.characteristics.add(ServiceCharacteristic.of((Map<String,Object>) req)); - } else { - throw new IllegalArgumentException("characteristics should be a map, not "+req.getClass()); - } - } - } else if (chars!=null) { - // TODO "map" short form - throw new IllegalArgumentException("services body should be iterable, not "+chars.getClass()); - } - - result.customAttributes = fields; - - return result; - } - - public String getName() { - return name; - } - public String getDescription() { - return description; - } - public String getServiceType() { - return serviceType; - } - public List<ServiceCharacteristic> getCharacteristics() { - return ImmutableList.copyOf(characteristics); - } - public Map<String, Object> getCustomAttributes() { - return ImmutableMap.copyOf(customAttributes); - } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ServiceCharacteristic.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ServiceCharacteristic.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ServiceCharacteristic.java deleted file mode 100644 index 8b27e2a..0000000 --- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ServiceCharacteristic.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 io.brooklyn.camp.spi.pdp; - -import java.util.Map; - -import org.apache.commons.lang3.builder.ToStringBuilder; - -import brooklyn.util.collections.MutableMap; -import brooklyn.util.yaml.Yamls; - -import com.google.common.collect.ImmutableMap; - -public class ServiceCharacteristic { - - String name; - String description; - String characteristicType; - - Map<String,Object> customAttributes; - - public static ServiceCharacteristic of(Map<String, Object> req) { - Map<String,Object> attrs = MutableMap.copyOf(req); - - ServiceCharacteristic result = new ServiceCharacteristic(); - result.name = (String) attrs.remove("name"); - result.description = (String) attrs.remove("description"); - result.characteristicType = (String) Yamls.removeMultinameAttribute(attrs, "characteristicType", "type"); - - // TODO fulfillment - - result.customAttributes = attrs; - - return result; - } - - public String getName() { - return name; - } - public String getDescription() { - return description; - } - public String getCharacteristicType() { - return characteristicType; - } - - public Map<String, Object> getCustomAttributes() { - return ImmutableMap.copyOf(customAttributes); - } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PdpMatcher.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PdpMatcher.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PdpMatcher.java deleted file mode 100644 index 94c8691..0000000 --- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PdpMatcher.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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 io.brooklyn.camp.spi.resolve; - -import io.brooklyn.camp.spi.pdp.Artifact; -import io.brooklyn.camp.spi.pdp.AssemblyTemplateConstructor; -import io.brooklyn.camp.spi.pdp.Service; - -/** Matchers build up the AssemblyTemplate by matching against items in the deployment plan */ -public interface PdpMatcher { - - boolean accepts(Object deploymentPlanItem); - boolean apply(Object deploymentPlanItem, AssemblyTemplateConstructor atc); - - public abstract class ArtifactMatcher implements PdpMatcher { - private String artifactType; - public ArtifactMatcher(String artifactType) { - this.artifactType = artifactType; - } - public boolean accepts(Object art) { - return (art instanceof Artifact) && this.artifactType.equals( ((Artifact)art).getArtifactType() ); - } - } - - public abstract class ServiceMatcher implements PdpMatcher { - private String serviceType; - public ServiceMatcher(String serviceType) { - this.serviceType = serviceType; - } - public boolean accepts(Object svc) { - return (svc instanceof Service) && this.serviceType.equals( ((Service)svc).getServiceType() ); - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PdpProcessor.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PdpProcessor.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PdpProcessor.java deleted file mode 100644 index e4bc537..0000000 --- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PdpProcessor.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * 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 io.brooklyn.camp.spi.resolve; - -import io.brooklyn.camp.CampPlatform; -import io.brooklyn.camp.spi.AssemblyTemplate; -import io.brooklyn.camp.spi.instantiate.BasicAssemblyTemplateInstantiator; -import io.brooklyn.camp.spi.pdp.Artifact; -import io.brooklyn.camp.spi.pdp.AssemblyTemplateConstructor; -import io.brooklyn.camp.spi.pdp.DeploymentPlan; -import io.brooklyn.camp.spi.pdp.Service; -import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationContext; -import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode; - -import java.io.InputStream; -import java.io.Reader; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.apache.commons.compress.archivers.ArchiveEntry; -import org.apache.commons.compress.archivers.ArchiveInputStream; -import org.apache.commons.compress.archivers.ArchiveStreamFactory; -import org.yaml.snakeyaml.error.YAMLException; - -import brooklyn.util.collections.MutableMap; -import brooklyn.util.exceptions.Exceptions; -import brooklyn.util.stream.Streams; -import brooklyn.util.yaml.Yamls; - -import com.google.common.annotations.VisibleForTesting; - -public class PdpProcessor { - - final CampPlatform campPlatform; - - final List<PdpMatcher> matchers = new ArrayList<PdpMatcher>(); - final List<PlanInterpreter> interpreters = new ArrayList<PlanInterpreter>(); - - public PdpProcessor(CampPlatform campPlatform) { - this.campPlatform = campPlatform; - } - - public DeploymentPlan parseDeploymentPlan(Reader yaml) { - return parseDeploymentPlan(Streams.readFully(yaml)); - } - - @SuppressWarnings("unchecked") - public DeploymentPlan parseDeploymentPlan(String yaml) { - Iterable<Object> template = Yamls.parseAll(yaml); - - Map<String, Object> dpRootUninterpreted = null; - try { - dpRootUninterpreted = Yamls.getAs(template, Map.class); - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - throw new YAMLException("Plan not in acceptable format: "+(e.getMessage()!=null ? e.getMessage() : ""+e), e); - } - Map<String, Object> dpRootInterpreted = applyInterpreters(dpRootUninterpreted); - - return DeploymentPlan.of(dpRootInterpreted, yaml); - } - - /** create and return an AssemblyTemplate based on the given DP (yaml) */ - public AssemblyTemplate registerDeploymentPlan(Reader yaml) { - DeploymentPlan plan = parseDeploymentPlan(yaml); - return registerDeploymentPlan(plan); - } - - /** applies matchers to the given deployment plan to create an assembly template */ - public AssemblyTemplate registerDeploymentPlan(DeploymentPlan plan) { - AssemblyTemplateConstructor atc = new AssemblyTemplateConstructor(campPlatform); - - if (plan.getName()!=null) atc.name(plan.getName()); - if (plan.getDescription()!=null) atc.description(plan.getDescription()); - if (plan.getSourceCode()!=null) atc.sourceCode(plan.getSourceCode()); - // nothing done with origin just now... - - if (plan.getServices()!=null) { - for (Service svc: plan.getServices()) { - applyMatchers(svc, atc); - } - } - - if (plan.getArtifacts()!=null) { - for (Artifact art: plan.getArtifacts()) { - applyMatchers(art, atc); - } - } - - Map<String, Object> attrs = plan.getCustomAttributes(); - if (attrs!=null && !attrs.isEmpty()) { - Map<String, Object> customAttrs = attrs; - if (customAttrs.containsKey("id")) { - // id shouldn't be leaking to entities, see InternalEntityFactory.createEntityAndDescendantsUninitialized. - // If set it will go through to the spec because AbstractBrooklynObject has @SetFromFlag("id") on the id property. - // Follows logic in BrooklynEntityMatcher.apply(...). - customAttrs = MutableMap.copyOf(attrs); - customAttrs.put("planId", customAttrs.remove("id")); - } - atc.addCustomAttributes(customAttrs); - } - - if (atc.getInstantiator()==null) - // set a default instantiator which just invokes the component's instantiators - // (or throws unsupported exceptions, currently!) - atc.instantiator(BasicAssemblyTemplateInstantiator.class); - - return atc.commit(); - } - - public AssemblyTemplate registerPdpFromArchive(InputStream archiveInput) { - try { - ArchiveInputStream input = new ArchiveStreamFactory() - .createArchiveInputStream(archiveInput); - - while (true) { - ArchiveEntry entry = input.getNextEntry(); - if (entry==null) break; - // TODO unpack entry, create a space on disk holding the archive ? - } - - // use yaml... - throw new UnsupportedOperationException("in progress"); - - } catch (Exception e) { - throw Exceptions.propagate(e); - } - } - - - // ---------------------------- - - public void addMatcher(PdpMatcher m) { - // TODO a list is a crude way to do matching ... but good enough to start - matchers.add(m); - } - - public List<PdpMatcher> getMatchers() { - return matchers; - } - - - protected void applyMatchers(Object deploymentPlanItem, AssemblyTemplateConstructor atc) { - for (PdpMatcher matcher: getMatchers()) { - if (matcher.accepts(deploymentPlanItem)) { - // TODO first accepting is a crude way to do matching ... but good enough to start - if (matcher.apply(deploymentPlanItem, atc)) - return; - } - } - throw new UnsupportedOperationException("Deployment plan item "+deploymentPlanItem+" cannot be matched"); - } - - // ---------------------------- - - public void addInterpreter(PlanInterpreter interpreter) { - interpreters.add(interpreter); - } - - /** returns a DeploymentPlan object which is the result of running the interpretation - * (with all interpreters) against the supplied deployment plan YAML object, - * essentially a post-parse processing step before matching */ - @SuppressWarnings("unchecked") - @VisibleForTesting - public Map<String, Object> applyInterpreters(Map<String, Object> originalDeploymentPlan) { - PlanInterpretationNode interpretation = new PlanInterpretationNode( - new PlanInterpretationContext(originalDeploymentPlan, interpreters)); - return (Map<String, Object>) interpretation.getNewValue(); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PlanInterpreter.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PlanInterpreter.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PlanInterpreter.java deleted file mode 100644 index 402de34..0000000 --- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PlanInterpreter.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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 io.brooklyn.camp.spi.resolve; - -import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode; - -import java.util.List; -import java.util.Map; - -/** Interpreters modify the deployment plan, in a depth-first evaluation, - * typically by looking for items which begin with "$namespace:" - * <p> - * Most common usages simple need to supply {@link #applyYamlPrimitive(PlanInterpretationNode)} which can invoke - * {@link PlanInterpretationNode#setNewValue(Object)} to change. - * The {@link PlanInterpreterAdapter} makes this easy by supplying all methods but that. - * <p> - * For more sophisticated usages, to act on entire maps or lists, - * there are a number of other hook functions, described below. - * */ -public interface PlanInterpreter { - - /** guard to prevent any apply calls when an Interpreter is not interested in a node */ - boolean isInterestedIn(PlanInterpretationNode node); - - /** provides an opportunity for an interpreter to change the value at a node, - * using {@link PlanInterpretationNode#get()} and {@link PlanInterpretationNode#setNewValue(Object)} */ - void applyYamlPrimitive(PlanInterpretationNode node); - - /** invoked at a Map node in a YAML tree, before any conversion to mapOut. - * mapIn is initially a copy of {@link PlanInterpretationNode#get()}, but it is mutable, - * and any mutations are passed to subsequent interpreters and used for recursion. - * <p> - * the return value indicates whether to recurse into the item. - * if any interpreters return false, the node is not recursed. - * (callers may use {@link PlanInterpretationNode#setNewValue(Object)} to set a custom return value.) */ - boolean applyMapBefore(PlanInterpretationNode node, Map<Object, Object> mapIn); - - /** invoked at a Map node in a YAML tree, after {@link #applyMapBefore(PlanInterpretationNode, Map)}, - * and after recursing into the value and then key arguments supplied here, - * but before inserting it into the mapOut for this node. - * <p> - * the return value indicates whether to add this key-value to the mapOut. - * if any interpreters return false, the entry is not added. - * (callers may modify mapOut to add/change values, or may modify key/value directly.) */ - boolean applyMapEntry(PlanInterpretationNode node, Map<Object, Object> mapIn, Map<Object, Object> mapOut, - PlanInterpretationNode key, PlanInterpretationNode value); - - /** invoked at a Map node in a YAML tree, after all entries have been passed to all interpreters' - * {@link #applyMapEntry(PlanInterpretationNode, Map, Map, PlanInterpretationNode, PlanInterpretationNode)}. - * mapOut can be modified yet further. */ - void applyMapAfter(PlanInterpretationNode node, Map<Object, Object> mapIn, Map<Object, Object> mapOut); - - /** as {@link #applyMapBefore(PlanInterpretationNode, Map)} but for lists */ - boolean applyListBefore(PlanInterpretationNode node, List<Object> listIn); - - /** as {@link #applyMapEntry(PlanInterpretationNode, Map, Map, PlanInterpretationNode, PlanInterpretationNode) but for lists */ - boolean applyListEntry(PlanInterpretationNode node, List<Object> listIn, List<Object> listOut, - PlanInterpretationNode value); - - /** as {@link #applyMapAfter(PlanInterpretationNode, Map, Map)} but for lists */ - void applyListAfter(PlanInterpretationNode node, List<Object> listIn, List<Object> listOut); - - - public abstract static class PlanInterpreterAdapter implements PlanInterpreter { - - @Override - public boolean applyMapBefore(PlanInterpretationNode node, Map<Object, Object> mapIn) { - return true; - } - - @Override - public boolean applyMapEntry(PlanInterpretationNode node, Map<Object, Object> mapIn, Map<Object, Object> mapOut, - PlanInterpretationNode key, PlanInterpretationNode value) { - return true; - } - - @Override - public void applyMapAfter(PlanInterpretationNode node, Map<Object, Object> mapIn, Map<Object, Object> mapOut) { - } - - @Override - public boolean applyListBefore(PlanInterpretationNode node, List<Object> listIn) { - return true; - } - - @Override - public boolean applyListEntry(PlanInterpretationNode node, List<Object> listIn, List<Object> listOut, - PlanInterpretationNode value) { - return true; - } - - @Override - public void applyListAfter(PlanInterpretationNode node, List<Object> listIn, List<Object> listOut) { - } - - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/interpret/PlanInterpretationContext.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/interpret/PlanInterpretationContext.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/interpret/PlanInterpretationContext.java deleted file mode 100644 index 3c1abc8..0000000 --- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/interpret/PlanInterpretationContext.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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 io.brooklyn.camp.spi.resolve.interpret; - -import io.brooklyn.camp.spi.resolve.PlanInterpreter; - -import java.util.List; -import java.util.Map; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; - -public class PlanInterpretationContext { - - private final Map<String,Object> originalDeploymentPlan; - private final List<PlanInterpreter> interpreters; - private final PlanInterpreter allInterpreter; - - public PlanInterpretationContext(Map<String,Object> originalDeploymentPlan, List<PlanInterpreter> interpreters) { - super(); - this.originalDeploymentPlan = ImmutableMap.copyOf(originalDeploymentPlan); - this.interpreters = ImmutableList.copyOf(interpreters); - this.allInterpreter = new PlanInterpreter() { - @Override - public boolean isInterestedIn(PlanInterpretationNode node) { - return true; - } - - @Override - public void applyYamlPrimitive(PlanInterpretationNode node) { - for (PlanInterpreter i: PlanInterpretationContext.this.interpreters) { - if (node.isExcluded()) - break; - if (i.isInterestedIn(node)) { - i.applyYamlPrimitive(node); - } - } - } - - @Override - public boolean applyMapBefore(PlanInterpretationNode node, Map<Object, Object> mapIn) { - boolean result = true; - for (PlanInterpreter i: PlanInterpretationContext.this.interpreters) { - if (node.isExcluded()) - break; - if (i.isInterestedIn(node)) { - boolean ri= i.applyMapBefore(node, mapIn); - result &= ri; - } - } - return result; - } - - @Override - public boolean applyMapEntry(PlanInterpretationNode node, Map<Object, Object> mapIn, Map<Object, Object> mapOut, - PlanInterpretationNode key, PlanInterpretationNode value) { - boolean result = true; - for (PlanInterpreter i: PlanInterpretationContext.this.interpreters) { - if (node.isExcluded()) - break; - if (i.isInterestedIn(key)) { - boolean ri = i.applyMapEntry(node, mapIn, mapOut, key, value); - result &= ri; - } - } - return result; - } - - @Override - public void applyMapAfter(PlanInterpretationNode node, Map<Object, Object> mapIn, Map<Object, Object> mapOut) { - for (PlanInterpreter i: PlanInterpretationContext.this.interpreters) { - if (node.isExcluded()) - break; - if (i.isInterestedIn(node)) { - i.applyMapAfter(node, mapIn, mapOut); - } - } - } - - @Override - public boolean applyListBefore(PlanInterpretationNode node, List<Object> listIn) { - boolean result = true; - for (PlanInterpreter i: PlanInterpretationContext.this.interpreters) { - if (node.isExcluded()) - break; - if (i.isInterestedIn(node)) { - boolean ri = i.applyListBefore(node, listIn); - result &= ri; - } - } - return result; - } - - @Override - public boolean applyListEntry(PlanInterpretationNode node, List<Object> listIn, List<Object> listOut, - PlanInterpretationNode value) { - boolean result = true; - for (PlanInterpreter i: PlanInterpretationContext.this.interpreters) { - if (node.isExcluded()) - break; - if (i.isInterestedIn(value)) { - boolean ri = i.applyListEntry(node, listIn, listOut, value); - result &= ri; - } - } - return result; - } - - @Override - public void applyListAfter(PlanInterpretationNode node, List<Object> listIn, List<Object> listOut) { - for (PlanInterpreter i: PlanInterpretationContext.this.interpreters) { - if (node.isExcluded()) - break; - if (i.isInterestedIn(node)) { - i.applyListAfter(node, listIn, listOut); - } - } - } - - }; - } - - /** returns an interpreter which recurses through all interpreters */ - PlanInterpreter getAllInterpreter() { - return allInterpreter; - } - - public Map<String,Object> getOriginalDeploymentPlan() { - return originalDeploymentPlan; - } - - public List<PlanInterpreter> getInterpreters() { - return interpreters; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/interpret/PlanInterpretationNode.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/interpret/PlanInterpretationNode.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/interpret/PlanInterpretationNode.java deleted file mode 100644 index 681df6b..0000000 --- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/interpret/PlanInterpretationNode.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * 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 io.brooklyn.camp.spi.resolve.interpret; - -import io.brooklyn.camp.spi.resolve.PlanInterpreter; - -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.util.collections.MutableList; -import brooklyn.util.collections.MutableMap; -import brooklyn.util.text.StringPredicates; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; - -/** Helper class for {@link PlanInterpreter} instances, doing the recursive work */ -public class PlanInterpretationNode { - - private static final Logger log = LoggerFactory.getLogger(PlanInterpretationNode.class); - - public enum Role { MAP_KEY, MAP_VALUE, LIST_ENTRY, YAML_PRIMITIVE } - - protected final PlanInterpretationNode parent; - protected final Role roleInParent; - protected final Object originalValue; - protected final PlanInterpretationContext context; - protected Object newValue = null; - protected Boolean changed = null; - protected boolean excluded = false; - protected boolean immutable = false; - - /** creates a root node with {@link #apply()} called */ - public PlanInterpretationNode(PlanInterpretationContext context) { - this.parent = null; - this.roleInParent = null; - this.originalValue = context.getOriginalDeploymentPlan(); - this.context = context; - apply(); - } - - /** internal use: creates an internal node on which {@link #apply()} has *not* been called */ - protected PlanInterpretationNode(PlanInterpretationNode parent, Role roleInParent, Object originalItem) { - this.parent = parent; - this.roleInParent = roleInParent; - this.originalValue = originalItem; - this.context = parent.getContext(); - } - - public PlanInterpretationContext getContext() { - return context; - } - - public PlanInterpretationNode getParent() { - return parent; - } - - public Role getRoleInParent() { - return roleInParent; - } - - protected void apply() { - if (changed!=null) throw new IllegalStateException("can only be applied once"); - - if (!excluded) { - if (originalValue instanceof Map) { - applyToMap(); - immutable(); - } else if (originalValue instanceof Iterable) { - applyToIterable(); - immutable(); - } else { - applyToYamlPrimitive(); - } - } - - if (changed==null) changed = false; - } - - /** convenience for interpreters, tests if nodes are not excluded, and if not: - * for string nodes, true iff the current value equals the given target; - * for nodes which are currently maps or lists, - * true iff not excluded and the value contains such an entry (key, in the case of map) - **/ - public boolean matchesLiteral(String target) { - if (isExcluded()) return false; - if (getNewValue() instanceof CharSequence) - return getNewValue().toString().equals(target); - if (getNewValue() instanceof Map) - return ((Map<?,?>)getOriginalValue()).containsKey(target); - if (getNewValue() instanceof Iterable) - return Iterables.contains((Iterable<?>)getOriginalValue(), target); - return false; - } - - /** convenience for interpreters, tests if nodes are not excluded, and if not: - * for string nodes, true iff the current value starts with the given prefix; - * for nodes which are currently maps or lists, - * true iff not excluded and the value contains such an entry (key, in the case of map) */ - public boolean matchesPrefix(String prefix) { - if (isExcluded()) return false; - if (getNewValue() instanceof CharSequence) - return getNewValue().toString().startsWith(prefix); - if (getNewValue() instanceof Map) - return Iterables.tryFind(((Map<?,?>)getNewValue()).keySet(), StringPredicates.isStringStartingWith(prefix)).isPresent(); - if (getNewValue() instanceof Iterable) - return Iterables.tryFind((Iterable<?>)getNewValue(), StringPredicates.isStringStartingWith(prefix)).isPresent(); - return false; - } - - // TODO matchesRegex ? - - public Object getOriginalValue() { - return originalValue; - } - - public Object getNewValue() { - if (changed==null || !isChanged()) return originalValue; - return newValue; - } - - public boolean isChanged() { - if (changed==null) throw new IllegalStateException("not yet applied"); - return changed; - } - - public boolean isExcluded() { - return excluded; - } - - /** indicates that a node should no longer be translated */ - public PlanInterpretationNode exclude() { - this.excluded = true; - return this; - } - - public PlanInterpretationNode setNewValue(Object newItem) { - if (immutable) - throw new IllegalStateException("Node "+this+" has been set immutable"); - this.newValue = newItem; - this.changed = true; - return this; - } - - protected PlanInterpretationNode newPlanInterpretation(PlanInterpretationNode parent, Role roleInParent, Object item) { - return new PlanInterpretationNode(parent, roleInParent, item); - } - - protected void applyToMap() { - Map<Object, Object> input = MutableMap.<Object,Object>copyOf((Map<?,?>)originalValue); - Map<Object, Object> result = MutableMap.<Object,Object>of(); - newValue = result; - - // first do a "whole-node" application - if (getContext().getAllInterpreter().applyMapBefore(this, input)) { - - for (Map.Entry<Object,Object> entry: input.entrySet()) { - // then recurse in to this node and do various in-the-node applications - PlanInterpretationNode value = newPlanInterpretation(this, Role.MAP_VALUE, entry.getValue()); - value.apply(); - - PlanInterpretationNode key = newPlanInterpretation(this, Role.MAP_KEY, entry.getKey()); - key.apply(); - - if (key.isChanged() || value.isChanged()) - changed = true; - - if (getContext().getAllInterpreter().applyMapEntry(this, input, result, key, value)) - result.put(key.getNewValue(), value.getNewValue()); - else - changed = true; - } - - // finally try applying to this node again - getContext().getAllInterpreter().applyMapAfter(this, input, result); - } - - if (changed==null) changed = false; - } - - protected void applyToIterable() { - MutableList<Object> input = MutableList.copyOf((Iterable<?>)originalValue); - MutableList<Object> result = new MutableList<Object>(); - newValue = result; - - // first do a "whole-node" application - if (getContext().getAllInterpreter().applyListBefore(this, input)) { - - for (Object entry: input) { - // then recurse in to this node and do various in-the-node applications - PlanInterpretationNode value = newPlanInterpretation(this, Role.LIST_ENTRY, entry); - value.apply(); - - if (value.isChanged()) - changed = true; - - if (getContext().getAllInterpreter().applyListEntry(this, input, result, value)) - result.add(value.getNewValue()); - } - - // finally try applying to this node again - getContext().getAllInterpreter().applyListAfter(this, input, result); - } - - if (changed==null) changed = false; - } - - protected void applyToYamlPrimitive() { - getContext().getAllInterpreter().applyYamlPrimitive(this); - } - - public void immutable() { - if (!isChanged()) { - if (!testCollectionImmutable(getNewValue())) { - // results of Yaml parse are not typically immutable, - // so force them to be changed so result of interpretation is immutable - changed = true; - setNewValue(immutable(getNewValue())); - } - } else { - setNewValue(immutable(getNewValue())); - } - checkImmutable(getNewValue()); - immutable = true; - } - - private void checkImmutable(Object in) { - if (!testCollectionImmutable(in)) - log.warn("Node original value "+in+" at "+this+" should be immutable"); - } - - private static boolean testCollectionImmutable(Object in) { - if (in instanceof Map) return (in instanceof ImmutableMap); - if (in instanceof Iterable) return (in instanceof ImmutableList); - return true; - } - - private static Object immutable(Object in) { - if (in instanceof Map) return ImmutableMap.copyOf((Map<?,?>)in); - if (in instanceof Iterable) return ImmutableList.copyOf((Iterable<?>)in); - return in; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/io/brooklyn/util/yaml/Yamls.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/io/brooklyn/util/yaml/Yamls.java b/camp/camp-base/src/main/java/io/brooklyn/util/yaml/Yamls.java deleted file mode 100644 index 44974f0..0000000 --- a/camp/camp-base/src/main/java/io/brooklyn/util/yaml/Yamls.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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 io.brooklyn.util.yaml; - -/** @deprecated since 0.7.0 use {@link brooklyn.util.yaml.Yamls} */ -@Deprecated -public class Yamls extends brooklyn.util.yaml.Yamls { -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/org/apache/brooklyn/camp/AggregatingCampPlatform.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/org/apache/brooklyn/camp/AggregatingCampPlatform.java b/camp/camp-base/src/main/java/org/apache/brooklyn/camp/AggregatingCampPlatform.java new file mode 100644 index 0000000..137e927 --- /dev/null +++ b/camp/camp-base/src/main/java/org/apache/brooklyn/camp/AggregatingCampPlatform.java @@ -0,0 +1,130 @@ +/* + * 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.brooklyn.camp; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Nullable; + +import org.apache.brooklyn.camp.spi.AbstractResource; +import org.apache.brooklyn.camp.spi.ApplicationComponent; +import org.apache.brooklyn.camp.spi.ApplicationComponentTemplate; +import org.apache.brooklyn.camp.spi.Assembly; +import org.apache.brooklyn.camp.spi.AssemblyTemplate; +import org.apache.brooklyn.camp.spi.PlatformComponent; +import org.apache.brooklyn.camp.spi.PlatformComponentTemplate; +import org.apache.brooklyn.camp.spi.PlatformRootSummary; +import org.apache.brooklyn.camp.spi.PlatformTransaction; +import org.apache.brooklyn.camp.spi.collection.AggregatingResourceLookup; +import org.apache.brooklyn.camp.spi.collection.ResourceLookup; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Function; + +/** A {@link CampPlatform} implementation which is empty but allows adding new items, + * as well as adding other platforms; meant for subclassing only */ +public class AggregatingCampPlatform extends CampPlatform { + + private static final Logger log = LoggerFactory.getLogger(AggregatingCampPlatform.class); + + protected AggregatingCampPlatform(PlatformRootSummary root) { + this(root, new BasicCampPlatform(root)); + } + + public AggregatingCampPlatform(PlatformRootSummary root, CampPlatform platformWhereTransactionsOccur) { + super(root); + log.debug("Creating {} with main platform: {}", this, platformWhereTransactionsOccur); + this.mainPlatform = platformWhereTransactionsOccur; + } + + /** platform where additions are made */ + CampPlatform mainPlatform; + List<CampPlatform> otherPlatformsToSearch = new ArrayList<CampPlatform>(); + + protected void addPlatform(CampPlatform platform) { + log.debug("Adding child platform to {}: {}", this, platform); + otherPlatformsToSearch.add(platform); + } + + protected <T extends AbstractResource> ResourceLookup<T> aggregatingLookup(Function<CampPlatform, ResourceLookup<T>> lookupFunction) { + List<ResourceLookup<T>> lookups = new ArrayList<ResourceLookup<T>>(); + lookups.add(lookupFunction.apply(mainPlatform)); + for (CampPlatform p: otherPlatformsToSearch) + lookups.add(lookupFunction.apply(p)); + return AggregatingResourceLookup.of(lookups); + } + + public ResourceLookup<PlatformComponentTemplate> platformComponentTemplates() { + return aggregatingLookup(new Function<CampPlatform, ResourceLookup<PlatformComponentTemplate>>() { + public ResourceLookup<PlatformComponentTemplate> apply(@Nullable CampPlatform input) { + return input.platformComponentTemplates(); + } + }); + } + + @Override + public ResourceLookup<ApplicationComponentTemplate> applicationComponentTemplates() { + return aggregatingLookup(new Function<CampPlatform, ResourceLookup<ApplicationComponentTemplate>>() { + public ResourceLookup<ApplicationComponentTemplate> apply(@Nullable CampPlatform input) { + return input.applicationComponentTemplates(); + } + }); + } + + public ResourceLookup<AssemblyTemplate> assemblyTemplates() { + return aggregatingLookup(new Function<CampPlatform, ResourceLookup<AssemblyTemplate>>() { + public ResourceLookup<AssemblyTemplate> apply(@Nullable CampPlatform input) { + return input.assemblyTemplates(); + } + }); + } + + public ResourceLookup<PlatformComponent> platformComponents() { + return aggregatingLookup(new Function<CampPlatform, ResourceLookup<PlatformComponent>>() { + public ResourceLookup<PlatformComponent> apply(@Nullable CampPlatform input) { + return input.platformComponents(); + } + }); + } + + @Override + public ResourceLookup<ApplicationComponent> applicationComponents() { + return aggregatingLookup(new Function<CampPlatform, ResourceLookup<ApplicationComponent>>() { + public ResourceLookup<ApplicationComponent> apply(@Nullable CampPlatform input) { + return input.applicationComponents(); + } + }); + } + + public ResourceLookup<Assembly> assemblies() { + return aggregatingLookup(new Function<CampPlatform, ResourceLookup<Assembly>>() { + public ResourceLookup<Assembly> apply(@Nullable CampPlatform input) { + return input.assemblies(); + } + }); + } + + @Override + public PlatformTransaction transaction() { + return mainPlatform.transaction(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/org/apache/brooklyn/camp/BasicCampPlatform.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/org/apache/brooklyn/camp/BasicCampPlatform.java b/camp/camp-base/src/main/java/org/apache/brooklyn/camp/BasicCampPlatform.java new file mode 100644 index 0000000..34fc6a2 --- /dev/null +++ b/camp/camp-base/src/main/java/org/apache/brooklyn/camp/BasicCampPlatform.java @@ -0,0 +1,142 @@ +/* + * 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.brooklyn.camp; + +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.brooklyn.camp.spi.ApplicationComponent; +import org.apache.brooklyn.camp.spi.ApplicationComponentTemplate; +import org.apache.brooklyn.camp.spi.Assembly; +import org.apache.brooklyn.camp.spi.AssemblyTemplate; +import org.apache.brooklyn.camp.spi.PlatformComponent; +import org.apache.brooklyn.camp.spi.PlatformComponentTemplate; +import org.apache.brooklyn.camp.spi.PlatformRootSummary; +import org.apache.brooklyn.camp.spi.PlatformTransaction; +import org.apache.brooklyn.camp.spi.collection.BasicResourceLookup; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** A {@link CampPlatform} implementation which is empty but allows adding new items */ +public class BasicCampPlatform extends CampPlatform { + + private static final Logger log = LoggerFactory.getLogger(BasicCampPlatform.class); + + public BasicCampPlatform() { + this(PlatformRootSummary.builder().name("CAMP Platform").build()); + } + + public BasicCampPlatform(PlatformRootSummary root) { + super(root); + } + + BasicResourceLookup<PlatformComponentTemplate> platformComponentTemplates = new BasicResourceLookup<PlatformComponentTemplate>(); + BasicResourceLookup<ApplicationComponentTemplate> applicationComponentTemplates = new BasicResourceLookup<ApplicationComponentTemplate>(); + BasicResourceLookup<AssemblyTemplate> assemblyTemplates = new BasicResourceLookup<AssemblyTemplate>(); + + BasicResourceLookup<PlatformComponent> platformComponents = new BasicResourceLookup<PlatformComponent>(); + BasicResourceLookup<ApplicationComponent> applicationComponents = new BasicResourceLookup<ApplicationComponent>(); + BasicResourceLookup<Assembly> assemblies = new BasicResourceLookup<Assembly>(); + + public BasicResourceLookup<PlatformComponentTemplate> platformComponentTemplates() { + return platformComponentTemplates; + } + + @Override + public BasicResourceLookup<ApplicationComponentTemplate> applicationComponentTemplates() { + return applicationComponentTemplates; + } + + public BasicResourceLookup<AssemblyTemplate> assemblyTemplates() { + return assemblyTemplates; + } + + public BasicResourceLookup<PlatformComponent> platformComponents() { + return platformComponents; + } + + @Override + public BasicResourceLookup<ApplicationComponent> applicationComponents() { + return applicationComponents; + } + + public BasicResourceLookup<Assembly> assemblies() { + return assemblies; + } + + @Override + public PlatformTransaction transaction() { + return new BasicPlatformTransaction(this); + } + + public static class BasicPlatformTransaction extends PlatformTransaction { + private final BasicCampPlatform platform; + private final AtomicBoolean committed = new AtomicBoolean(false); + + public BasicPlatformTransaction(BasicCampPlatform platform) { + this.platform = platform; + } + + @Override + public void commit() { + if (committed.getAndSet(true)) + throw new IllegalStateException("transaction being committed multiple times"); + + for (Object o: additions) { + if (o instanceof AssemblyTemplate) { + platform.assemblyTemplates.add((AssemblyTemplate) o); + continue; + } + if (o instanceof PlatformComponentTemplate) { + platform.platformComponentTemplates.add((PlatformComponentTemplate) o); + continue; + } + if (o instanceof ApplicationComponentTemplate) { + platform.applicationComponentTemplates.add((ApplicationComponentTemplate) o); + continue; + } + + if (o instanceof Assembly) { + platform.assemblies.add((Assembly) o); + continue; + } + if (o instanceof PlatformComponent) { + platform.platformComponents.add((PlatformComponent) o); + continue; + } + if (o instanceof ApplicationComponent) { + platform.applicationComponents.add((ApplicationComponent) o); + continue; + } + + throw new UnsupportedOperationException("Object "+o+" of type "+o.getClass()+" cannot be added to "+platform); + } + } + + @Override + protected void finalize() throws Throwable { + if (!committed.get()) { + // normal, in the case of errors (which might occur when catalog tries to figure out the right plan format); shouldn't happen otherwise + // if we want log.warn visibility of these, then we will have to supply an abandon() method on this interface and ensure that is invoked on errors + log.debug("transaction "+this+" was never applied"); + } + super.finalize(); + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/org/apache/brooklyn/camp/CampPlatform.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/org/apache/brooklyn/camp/CampPlatform.java b/camp/camp-base/src/main/java/org/apache/brooklyn/camp/CampPlatform.java new file mode 100644 index 0000000..817dae8 --- /dev/null +++ b/camp/camp-base/src/main/java/org/apache/brooklyn/camp/CampPlatform.java @@ -0,0 +1,76 @@ +/* + * 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.brooklyn.camp; + +import org.apache.brooklyn.camp.spi.ApplicationComponent; +import org.apache.brooklyn.camp.spi.ApplicationComponentTemplate; +import org.apache.brooklyn.camp.spi.Assembly; +import org.apache.brooklyn.camp.spi.AssemblyTemplate; +import org.apache.brooklyn.camp.spi.PlatformComponent; +import org.apache.brooklyn.camp.spi.PlatformComponentTemplate; +import org.apache.brooklyn.camp.spi.PlatformRootSummary; +import org.apache.brooklyn.camp.spi.PlatformTransaction; +import org.apache.brooklyn.camp.spi.collection.ResourceLookup; +import org.apache.brooklyn.camp.spi.resolve.PdpProcessor; + +import com.google.common.base.Preconditions; + +public abstract class CampPlatform { + + private final PlatformRootSummary root; + private final PdpProcessor pdp; + + public CampPlatform(PlatformRootSummary root) { + this.root = Preconditions.checkNotNull(root, "root"); + pdp = createPdpProcessor(); + } + + // --- root + + public PlatformRootSummary root() { + return root; + } + + // --- other aspects + + public PdpProcessor pdp() { + return pdp; + } + + + // --- required custom implementation hooks + + public abstract ResourceLookup<PlatformComponentTemplate> platformComponentTemplates(); + public abstract ResourceLookup<ApplicationComponentTemplate> applicationComponentTemplates(); + public abstract ResourceLookup<AssemblyTemplate> assemblyTemplates(); + + public abstract ResourceLookup<PlatformComponent> platformComponents(); + public abstract ResourceLookup<ApplicationComponent> applicationComponents(); + public abstract ResourceLookup<Assembly> assemblies(); + + /** returns object where changes to a PDP can be made; note all changes must be committed */ + public abstract PlatformTransaction transaction(); + + // --- optional customisation overrides + + protected PdpProcessor createPdpProcessor() { + return new PdpProcessor(this); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/org/apache/brooklyn/camp/commontypes/RepresentationSkew.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/org/apache/brooklyn/camp/commontypes/RepresentationSkew.java b/camp/camp-base/src/main/java/org/apache/brooklyn/camp/commontypes/RepresentationSkew.java new file mode 100644 index 0000000..01cece9 --- /dev/null +++ b/camp/camp-base/src/main/java/org/apache/brooklyn/camp/commontypes/RepresentationSkew.java @@ -0,0 +1,23 @@ +/* + * 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.brooklyn.camp.commontypes; + +public enum RepresentationSkew { + CREATING, NONE, DESTROYING, UNKNOWN +} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7d782f34/camp/camp-base/src/main/java/org/apache/brooklyn/camp/spi/AbstractResource.java ---------------------------------------------------------------------- diff --git a/camp/camp-base/src/main/java/org/apache/brooklyn/camp/spi/AbstractResource.java b/camp/camp-base/src/main/java/org/apache/brooklyn/camp/spi/AbstractResource.java new file mode 100644 index 0000000..0a01d45 --- /dev/null +++ b/camp/camp-base/src/main/java/org/apache/brooklyn/camp/spi/AbstractResource.java @@ -0,0 +1,197 @@ +/* + * 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.brooklyn.camp.spi; + +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.apache.brooklyn.camp.commontypes.RepresentationSkew; + +import brooklyn.util.collections.MutableMap; +import brooklyn.util.text.Identifiers; +import brooklyn.util.time.Time; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +/** Superclass of CAMP resource implementation objects. + * Typically used to hold common state of implementation objects + * and to populate the DTO's used by the REST API. + * <p> + * These class instances are typically created using the + * static {@link #builder()} methods they contain. + * The resulting instances are typically immutable, + * so where fields can change callers should use a new builder + * (or update an underlying data store). + * <p> + * This class is not meant to be instantiated directly, as + * CAMP only uses defined subclasses (ie containing these fields). + * It is instantiable for testing. + */ +public class AbstractResource { + + public static final String CAMP_TYPE = "Resource"; + + private String id = Identifiers.makeRandomId(8); + private String name; + private String type; + private String description; + private String sourceCode; + private Date created = Time.dropMilliseconds(new Date()); + private List<String> tags = Collections.emptyList(); + private RepresentationSkew representationSkew; + + private Map<String,Object> customAttributes = new MutableMap<String, Object>(); + + /** Use {@link #builder()} to create */ + protected AbstractResource() {} + + // getters + + public String getId() { + return id; + } + public String getName() { + return name; + } + public String getType() { + return type; + } + public String getDescription() { + return description; + } + public String getSourceCode() { + return sourceCode; + } + public Date getCreated() { + return created; + } + public List<String> getTags() { + return tags; + } + public RepresentationSkew getRepresentationSkew() { + return representationSkew; + } + public Map<String, Object> getCustomAttributes() { + return ImmutableMap.copyOf(customAttributes); + } + + // setters + + private void setId(String id) { + this.id = id; + } + private void setName(String name) { + this.name = name; + } + private void setDescription(String description) { + this.description = description; + } + private void setSourceCode(String sourceCode) { + this.sourceCode = sourceCode; + } + private void setCreated(Date created) { + // precision beyond seconds breaks equals check + this.created = Time.dropMilliseconds(created); + } + private void setTags(List<String> tags) { + this.tags = ImmutableList.copyOf(tags); + } + private void setType(String type) { + this.type = type; + } + private void setRepresentationSkew(RepresentationSkew representationSkew) { + this.representationSkew = representationSkew; + } + public void setCustomAttribute(String key, Object value) { + this.customAttributes.put(key, value); + } + + // builder + @SuppressWarnings("rawtypes") + public static Builder<? extends AbstractResource,? extends Builder> builder() { + return new AbstractResource().new AbstractResourceBuilder(CAMP_TYPE); + } + + /** Builder creates the instance up front to avoid repetition of fields in the builder; + * but prevents object leakage until build and prevents changes after build, + * so effectively immutable. + * <p> + * Similarly setters in the class are private so those objects are also typically effectively immutable. */ + public abstract class Builder<T extends AbstractResource,U extends Builder<T,U>> { + + private boolean built = false; + private String type = null; + private boolean initialized = false; + + protected Builder(String type) { + this.type = type; + } + + protected final synchronized void check() { + if (built) + throw new IllegalStateException("Builder instance from "+this+" cannot be access after build"); + if (!initialized) { + initialized = true; + initialize(); + } + } + + protected void initialize() { + if (type!=null) type(type); + } + + @SuppressWarnings("unchecked") + public synchronized T build() { + check(); + built = true; + return (T) AbstractResource.this; + } + + @SuppressWarnings("unchecked") + protected U thisBuilder() { return (U)this; } + + public U type(String x) { check(); AbstractResource.this.setType(x); return thisBuilder(); } + public U id(String x) { check(); AbstractResource.this.setId(x); return thisBuilder(); } + public U name(String x) { check(); AbstractResource.this.setName(x); return thisBuilder(); } + public U description(String x) { check(); AbstractResource.this.setDescription(x); return thisBuilder(); } + public U created(Date x) { check(); AbstractResource.this.setCreated(x); return thisBuilder(); } + public U tags(List<String> x) { check(); AbstractResource.this.setTags(x); return thisBuilder(); } + public U representationSkew(RepresentationSkew x) { check(); AbstractResource.this.setRepresentationSkew(x); return thisBuilder(); } + public U customAttribute(String key, Object value) { check(); AbstractResource.this.setCustomAttribute(key, value); return thisBuilder(); } + public U sourceCode(String x) { check(); AbstractResource.this.setSourceCode(x); return thisBuilder(); } + +// public String type() { return instance().type; } + } + + @VisibleForTesting + protected class AbstractResourceBuilder extends Builder<AbstractResource,AbstractResourceBuilder> { + protected AbstractResourceBuilder(String type) { + super(type); + } + } + + @Override + public String toString() { + return super.toString()+"[id="+getId()+"; type="+getType()+"]"; + } +}
