/* * 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.applib.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.List; import com.google.common.base.Function; import com.google.common.base.Splitter; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; /** * Specifies the positioning of an entity's (groups of) properties and of its collections, on a page, column by column. * * <p> * The left column and middle column determine the ordering of the entity's (groups of) properties. The * value of the {@link #left() left} list and {@link #middle() middle} list specify the order * of the property groups (inferred from each property's {@link MemberOrder#name() MemberOrder.name} attribute. * * <p> * The right column is for the entity's collections. The order of this collections is simply as * determined by the collection's {@link MemberOrder#sequence() MemberOrder.sequence} attribute * * <p> * If both this annotation, {@link MemberGroupLayout}, and {@link MemberGroups} annotation * are present on an entity, then this one takes precedence. * * <p> * The recommended alternative is to use the <code>Xxx.layout.xml</code> file, where <code>Xxx</code> is the domain object name. * </p> * * @deprecated */ @Deprecated @Inherited @Target({ ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface MemberGroupLayout { /** * The relative widths of the columns of members. */ public static class ColumnSpans { private final int left; private final int middle; private final int right; private final int collections; public static ColumnSpans valueOf(String str) { final Iterable<String> split = Splitter.on(",").split(str); try { final List<Integer> list = Lists.newArrayList(Iterables.transform(split, new Function<String,Integer>() { @Override public Integer apply(String input) { return Integer.parseInt(input); } })); return asSpans(list); } catch(RuntimeException ex) { return null; } } public static ColumnSpans asSpans(int... columnSpans) { List<Integer> list = Lists.<Integer>newArrayList(); for (int i : columnSpans) { list.add(i); } return asSpans(list); } private static ColumnSpans asSpans(List<Integer> list) { return new ColumnSpans(list); } private ColumnSpans(List<Integer> list) { this.left = getElse(list,0,4); this.middle = getElse(list,1,0); this.right = getElse(list,2,0); this.collections = getElse(list,3,8); } private static int getElse(List<Integer> list, int i, int dflt) { return list != null && list.size() > i? list.get(i): dflt; } public int getLeft() { return left; } public int getMiddle() { return middle; } public int getRight() { return right; } public int getCollections() { return collections; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + collections; result = prime * result + left; result = prime * result + middle; result = prime * result + right; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; ColumnSpans other = (ColumnSpans) obj; if (collections != other.collections) return false; if (left != other.left) return false; if (middle != other.middle) return false; if (right != other.right) return false; return true; } public String name() { return String.format("[%d,%d,%d,%d]", left, middle, right, collections); } public boolean exceedsRow() { return getLeft() + getMiddle() + getRight() + getCollections() > 12; } } /** * Specify the spans of each of the columns. * * <p> * The sum of the spans is always 12. */ int[] columnSpans() default {4,0,0,8}; /** * Order of groups of properties as they appear in the left-most column of a webpage, * grouped as they appear as the <tt>name</tt> attribute of the {@link MemberOrder} * annotation. * * <p> * The order in this list determines the order that the property groups will be rendered. * By convention any {@link MemberOrder} that does not have a {@link MemberOrder#name() name} is considered * to be in the default group, whose name is hard-coded as <i>General</i>. * * <p> * Equivalent to {@link MemberGroups#value()} annotation. */ String[] left() default {}; /** * As {@link #left()}, but for the middle column in a page. * * <p> * If the value of this attribute is non-empty but the {@link #columnSpans()} specifies a zero size, then the * framework will not boot and will instead indicate a meta-model validation exception. */ String[] middle() default {}; /** * As {@link #right()}, but for the right column in a page. * * <p> * If the value of this attribute is non-empty but the {@link #columnSpans()} specifies a zero size, then the * framework will not boot and will instead indicate a meta-model validation exception. */ String[] right() default {}; }