001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.isis.viewer.restfulobjects.rendering.domainobjects; 018 019import java.util.Map; 020 021import org.apache.isis.applib.annotation.ActionSemantics; 022import org.apache.isis.applib.util.Enums; 023import org.apache.isis.core.metamodel.facets.actions.invoke.ActionInvocationFacet; 024import org.apache.isis.core.metamodel.facets.collections.modify.CollectionAddToFacet; 025import org.apache.isis.core.metamodel.facets.collections.modify.CollectionRemoveFromFacet; 026import org.apache.isis.core.metamodel.facets.properties.modify.PropertyClearFacet; 027import org.apache.isis.core.metamodel.facets.properties.modify.PropertySetterFacet; 028import org.apache.isis.core.metamodel.spec.ObjectSpecification; 029import org.apache.isis.core.metamodel.spec.feature.ObjectAction; 030import org.apache.isis.core.metamodel.spec.feature.ObjectFeature; 031import org.apache.isis.core.metamodel.spec.feature.ObjectMember; 032import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation; 033import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation; 034import org.apache.isis.core.progmodel.facets.actions.validate.ActionValidationFacet; 035import org.apache.isis.core.progmodel.facets.collections.validate.CollectionValidateAddToFacet; 036import org.apache.isis.core.progmodel.facets.collections.validate.CollectionValidateRemoveFromFacet; 037import org.apache.isis.core.progmodel.facets.properties.validate.PropertyValidateFacet; 038import org.apache.isis.viewer.restfulobjects.applib.Rel; 039import org.apache.isis.viewer.restfulobjects.applib.RepresentationType; 040import org.apache.isis.viewer.restfulobjects.applib.RestfulHttpMethod; 041 042import com.google.common.collect.ImmutableMap; 043 044public enum MemberType { 045 046 PROPERTY("properties/", RepresentationType.OBJECT_PROPERTY, 047 ImmutableMap.of( 048 "modify", MutatorSpec.of(Rel.MODIFY, PropertyValidateFacet.class, PropertySetterFacet.class, RestfulHttpMethod.PUT, BodyArgs.ONE), 049 "clear", MutatorSpec.of(Rel.CLEAR, PropertyValidateFacet.class, PropertyClearFacet.class, RestfulHttpMethod.DELETE, BodyArgs.NONE))) { 050 @Override 051 public ObjectSpecification specFor(final ObjectMember objectMember) { 052 return objectMember.getSpecification(); 053 } 054 }, 055 /** 056 * {@link #getMutators()} are keyed by 057 * {@link CollectionSemantics#getAddToKey()} 058 */ 059 COLLECTION("collections/", RepresentationType.OBJECT_COLLECTION, 060 ImmutableMap.of( 061 "addToSet", MutatorSpec.of(Rel.ADD_TO, CollectionValidateAddToFacet.class, CollectionAddToFacet.class, RestfulHttpMethod.PUT, BodyArgs.ONE), 062 "addToList", MutatorSpec.of(Rel.ADD_TO, CollectionValidateAddToFacet.class, CollectionAddToFacet.class, RestfulHttpMethod.POST, BodyArgs.ONE), "removeFrom", MutatorSpec.of(Rel.REMOVE_FROM, CollectionValidateRemoveFromFacet.class, CollectionRemoveFromFacet.class, RestfulHttpMethod.DELETE, BodyArgs.ONE))) { 063 @Override 064 public ObjectSpecification specFor(final ObjectMember objectMember) { 065 return objectMember.getSpecification(); 066 } 067 }, 068 /** 069 * {@link #getMutators()} are keyed by 070 * {@link ActionSemantics#getInvokeKey()} 071 */ 072 ACTION("actions/", RepresentationType.OBJECT_ACTION, 073 ImmutableMap.of( 074 "invokeQueryOnly", MutatorSpec.of(Rel.INVOKE, ActionValidationFacet.class, ActionInvocationFacet.class, RestfulHttpMethod.GET, BodyArgs.MANY, "invoke"), 075 "invokeIdempotent", MutatorSpec.of(Rel.INVOKE, ActionValidationFacet.class, ActionInvocationFacet.class, RestfulHttpMethod.PUT, BodyArgs.MANY, "invoke"), 076 "invoke", MutatorSpec.of(Rel.INVOKE, ActionValidationFacet.class, ActionInvocationFacet.class, RestfulHttpMethod.POST, BodyArgs.MANY, "invoke"))) { 077 @Override 078 public ObjectSpecification specFor(final ObjectMember objectMember) { 079 final ObjectAction objectAction = (ObjectAction) objectMember; 080 return objectAction.getReturnType(); 081 } 082 }; 083 084 private final String urlPart; 085 private final String name; 086 private final RepresentationType representationType; 087 088 private final Map<String, MutatorSpec> mutators; 089 090 private MemberType(final String urlPart, final RepresentationType representationType, final Map<String, MutatorSpec> mutators) { 091 this.urlPart = urlPart; 092 this.representationType = representationType; 093 this.mutators = mutators; 094 name = Enums.enumToCamelCase(this); 095 } 096 097 public String getUrlPart() { 098 return urlPart; 099 } 100 101 public Map<String, MutatorSpec> getMutators() { 102 return mutators; 103 } 104 105 public abstract ObjectSpecification specFor(ObjectMember objectMember); 106 107 public boolean isProperty() { 108 return this == MemberType.PROPERTY; 109 } 110 111 public boolean isCollection() { 112 return this == MemberType.COLLECTION; 113 } 114 115 public boolean isAction() { 116 return this == MemberType.ACTION; 117 } 118 119 public static MemberType lookup(final String memberTypeName) { 120 for (final MemberType memberType : values()) { 121 if (memberType.getName().equals(memberTypeName)) { 122 return memberType; 123 } 124 } 125 return null; 126 } 127 128 public static MemberType of(final ObjectMember objectMember) { 129 return objectMember.isAction() ? ACTION : objectMember.isOneToOneAssociation() ? PROPERTY : COLLECTION; 130 } 131 132 public RepresentationType getRepresentationType() { 133 return representationType; 134 } 135 136 public String getName() { 137 return name; 138 } 139 140 public static MemberType determineFrom(final ObjectFeature objectFeature) { 141 if (objectFeature instanceof ObjectAction) { 142 return MemberType.ACTION; 143 } 144 if (objectFeature instanceof OneToOneAssociation) { 145 return MemberType.PROPERTY; 146 } 147 if (objectFeature instanceof OneToManyAssociation) { 148 return MemberType.COLLECTION; 149 } 150 return null; 151 } 152 153}