/* * 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.isis.core.metamodel.services.appfeat; import java.util.SortedSet; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import org.apache.isis.applib.IsisApplibModule; import org.apache.isis.applib.annotation.Programmatic; import org.apache.isis.applib.annotation.SemanticsOf; import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository; import org.apache.isis.applib.services.appfeat.ApplicationMemberType; import org.apache.isis.applib.util.ObjectContracts; /** * Canonical application feature, identified by {@link ApplicationFeatureId}, * and wired together with other application features and cached by {@link ApplicationFeatureRepository}. * * <p> * Note that this is NOT a view model; instead it can be converted to a string using methods of * {@link ApplicationFeatureRepository}, eg {@link ApplicationFeatureRepository#classNamesContainedIn(String, ApplicationMemberType)}. * </p> */ public class ApplicationFeature implements Comparable<ApplicationFeature> { public static abstract class PropertyDomainEvent<T> extends IsisApplibModule.PropertyDomainEvent<ApplicationFeature, T> {} public static abstract class CollectionDomainEvent<T> extends IsisApplibModule.CollectionDomainEvent<ApplicationFeature, T> {} public static abstract class ActionDomainEvent extends IsisApplibModule.ActionDomainEvent<ApplicationFeature> {} //region > constants // using same value for all to neaten up rendering public static final int TYPICAL_LENGTH_PKG_FQN = 50; public static final int TYPICAL_LENGTH_CLS_NAME = 50; public static final int TYPICAL_LENGTH_MEMBER_NAME = 50; //endregion //region > constructors public ApplicationFeature() { this(null); } public ApplicationFeature(final ApplicationFeatureId featureId) { setFeatureId(featureId); } //endregion //region > featureId private ApplicationFeatureId featureId; @Programmatic public ApplicationFeatureId getFeatureId() { return featureId; } public void setFeatureId(final ApplicationFeatureId applicationFeatureId) { this.featureId = applicationFeatureId; } //endregion //region > memberType private ApplicationMemberType memberType; /** * Only for {@link ApplicationFeatureType#MEMBER member}s. */ @Programmatic public ApplicationMemberType getMemberType() { return memberType; } public void setMemberType(final ApplicationMemberType memberType) { this.memberType = memberType; } //endregion //region > returnTypeName (for: properties, collections, actions) private String returnTypeName; /** * Only for {@link ApplicationMemberType#ACTION action}s. */ @Programmatic public String getReturnTypeName() { return returnTypeName; } public void setReturnTypeName(final String returnTypeName) { this.returnTypeName = returnTypeName; } //endregion //region > contributed (for: properties, collections, actions) private boolean contributed; @Programmatic public boolean isContributed() { return contributed; } public void setContributed(final boolean contributed) { this.contributed = contributed; } //endregion //region > derived (properties and collections) private Boolean derived; /** * Only for {@link ApplicationMemberType#PROPERTY} and {@link ApplicationMemberType#COLLECTION} */ @Programmatic public Boolean isDerived() { return derived; } public void setDerived(final Boolean derived) { this.derived = derived; } //endregion //region > propertyMaxLength (properties only) private Integer propertyMaxLength; /** * Only for {@link ApplicationMemberType#ACTION action}s. */ @Programmatic public Integer getPropertyMaxLength() { return propertyMaxLength; } public void setPropertyMaxLength(final Integer propertyMaxLength) { this.propertyMaxLength = propertyMaxLength; } //endregion //region > propertyTypicalLength (properties only) private Integer propertyTypicalLength; /** * Only for {@link ApplicationMemberType#ACTION action}s. */ @Programmatic public Integer getPropertyTypicalLength() { return propertyTypicalLength; } public void setPropertyTypicalLength(final Integer propertyTypicalLength) { this.propertyTypicalLength = propertyTypicalLength; } //endregion //region > actionSemantics (actions only) private SemanticsOf actionSemantics; /** * Only for {@link ApplicationMemberType#ACTION action}s. */ @Programmatic public SemanticsOf getActionSemantics() { return actionSemantics; } public void setActionSemantics(final SemanticsOf actionSemantics) { this.actionSemantics = actionSemantics; } //endregion //region > packages: Contents private final SortedSet<ApplicationFeatureId> contents = Sets.newTreeSet(); @Programmatic public SortedSet<ApplicationFeatureId> getContents() { ApplicationFeatureType.ensurePackage(this.getFeatureId()); return contents; } @Programmatic public void addToContents(final ApplicationFeatureId contentId) { ApplicationFeatureType.ensurePackage(this.getFeatureId()); ApplicationFeatureType.ensurePackageOrClass(contentId); this.contents.add(contentId); } //endregion //region > classes: Properties, Collections, Actions private final SortedSet<ApplicationFeatureId> properties = Sets.newTreeSet(); @Programmatic public SortedSet<ApplicationFeatureId> getProperties() { ApplicationFeatureType.ensureClass(this.getFeatureId()); return properties; } private final SortedSet<ApplicationFeatureId> collections = Sets.newTreeSet(); @Programmatic public SortedSet<ApplicationFeatureId> getCollections() { ApplicationFeatureType.ensureClass(this.getFeatureId()); return collections; } private final SortedSet<ApplicationFeatureId> actions = Sets.newTreeSet(); @Programmatic public SortedSet<ApplicationFeatureId> getActions() { ApplicationFeatureType.ensureClass(this.getFeatureId()); return actions; } @Programmatic public void addToMembers(final ApplicationFeatureId memberId, final ApplicationMemberType memberType) { ApplicationFeatureType.ensureClass(this.getFeatureId()); ApplicationFeatureType.ensureMember(memberId); membersOf(memberType).add(memberId); } @Programmatic public SortedSet<ApplicationFeatureId> membersOf(final ApplicationMemberType memberType) { ApplicationFeatureType.ensureClass(this.getFeatureId()); switch (memberType) { case PROPERTY: return properties; case COLLECTION: return collections; default: // case ACTION: return actions; } } //endregion //region > Functions public static class Functions { private Functions(){} public static final Function<? super ApplicationFeature, ? extends String> GET_FQN = new Function<ApplicationFeature, String>() { @Override public String apply(final ApplicationFeature input) { return input.getFeatureId().getFullyQualifiedName(); } }; public static final Function<ApplicationFeature, ApplicationFeatureId> GET_ID = new Function<ApplicationFeature, ApplicationFeatureId>() { @Override public ApplicationFeatureId apply(final ApplicationFeature input) { return input.getFeatureId(); } }; } public static class Predicates { private Predicates(){} public static Predicate<ApplicationFeature> packageContainingClasses( final ApplicationMemberType memberType, final ApplicationFeatureRepositoryDefault applicationFeatures) { return new Predicate<ApplicationFeature>() { @Override public boolean apply(final ApplicationFeature input) { // all the classes in this package final Iterable<ApplicationFeatureId> classIds = Iterables.filter(input.getContents(), ApplicationFeatureId.Predicates.isClassContaining(memberType, applicationFeatures)); return classIds.iterator().hasNext(); } }; } } //endregion //region > equals, hashCode, compareTo, toString private final static String propertyNames = "featureId"; @Override public int compareTo(final ApplicationFeature other) { return ObjectContracts.compare(this, other, propertyNames); } @Override public boolean equals(final Object obj) { return ObjectContracts.equals(this, obj, propertyNames); } @Override public int hashCode() { return ObjectContracts.hashCode(this, propertyNames); } @Override public String toString() { return ObjectContracts.toString(this, propertyNames); } //endregion }