http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ServiceActionsModel.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ServiceActionsModel.java b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ServiceActionsModel.java new file mode 100644 index 0000000..d0bcc36 --- /dev/null +++ b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ServiceActionsModel.java @@ -0,0 +1,74 @@ +/* + * 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.viewer.wicket.model.models; + +import java.util.List; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import org.apache.isis.applib.annotation.DomainServiceLayout; +import org.apache.isis.core.metamodel.adapter.ObjectAdapter; +import org.apache.isis.core.metamodel.facets.object.domainservicelayout.DomainServiceLayoutFacet; + +/** + * Backing model for actions of application services menu bar (typically, as + * displayed along the top or side of the page). + */ +public class ServiceActionsModel extends ModelAbstract<List<ObjectAdapter>> { + + private static final long serialVersionUID = 1L; + + private final DomainServiceLayout.MenuBar menuBar; + + /** + * @param menuBar - may be null in special case of rendering the tertiary menu on the error page. + */ + public ServiceActionsModel(final DomainServiceLayout.MenuBar menuBar) { + this.menuBar = menuBar; + } + + /** + * The menu bar being rendered; may be null in special case of rendering the tertiary menu on the error page. + */ + public DomainServiceLayout.MenuBar getMenuBar() { + return menuBar; + } + + protected List<ObjectAdapter> load() { + return Lists.newArrayList(Iterables.filter(getServiceAdapters(), with(menuBar))); + } + + private static Predicate<ObjectAdapter> with(final DomainServiceLayout.MenuBar menuBar) { + return new Predicate<ObjectAdapter>() { + @Override + public boolean apply(ObjectAdapter input) { + final DomainServiceLayoutFacet facet = input.getSpecification().getFacet + (DomainServiceLayoutFacet.class); + return facet != null && facet.getMenuBar() == menuBar; + } + }; + } + + protected List<ObjectAdapter> getServiceAdapters() { + return getPersistenceSession().getServices(); + } + + +}
http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ValueModel.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ValueModel.java b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ValueModel.java new file mode 100644 index 0000000..9ddd054 --- /dev/null +++ b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ValueModel.java @@ -0,0 +1,66 @@ +/* + * 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.viewer.wicket.model.models; + +import org.apache.isis.core.metamodel.adapter.ObjectAdapter; +import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking; +import org.apache.isis.core.metamodel.spec.feature.ObjectAction; +import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento; + +/** + * Represents a standalone value. + */ +public class ValueModel extends ModelAbstract<ObjectAdapter> { + + private static final long serialVersionUID = 1L; + + private final ObjectAdapterMemento adapterMemento; + + public ValueModel(final ObjectAdapter adapter) { + adapterMemento = ObjectAdapterMemento.createOrNull(adapter); + } + + @Override + protected ObjectAdapter load() { + return adapterMemento.getObjectAdapter(ConcurrencyChecking.NO_CHECK); + } + + // ////////////////////////////////////// + + private ActionModel actionModelHint; + /** + * The {@link ActionModel model} of the {@link ObjectAction action} + * that generated this {@link ValueModel}. + * + * @see #setActionHint(ActionModel) + */ + public ActionModel getActionModelHint() { + return actionModelHint; + } + /** + * Called by action. + * + * @see #getActionModelHint() + */ + public void setActionHint(ActionModel actionModelHint) { + this.actionModelHint = actionModelHint; + } + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/VoidModel.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/VoidModel.java b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/VoidModel.java new file mode 100644 index 0000000..c0437d3 --- /dev/null +++ b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/VoidModel.java @@ -0,0 +1,61 @@ +/* + * 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.viewer.wicket.model.models; + +import org.apache.isis.core.metamodel.spec.feature.ObjectAction; + + +/** + * Represents the result of invoking a <tt>void</tt> action. + */ +public class VoidModel extends ModelAbstract<Void> { + + private static final long serialVersionUID = 1L; + + public VoidModel() { + } + + @Override + protected Void load() { + return null; + } + + + // ////////////////////////////////////// + + private ActionModel actionModelHint; + /** + * The {@link ActionModel model} of the {@link ObjectAction action} + * that generated this {@link VoidModel}. + * + * @see #setActionHint(ActionModel) + */ + public ActionModel getActionModelHint() { + return actionModelHint; + } + /** + * Called by action. + * + * @see #getActionModelHint() + */ + public void setActionHint(ActionModel actionModelHint) { + this.actionModelHint = actionModelHint; + } +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/WelcomeModel.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/WelcomeModel.java b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/WelcomeModel.java new file mode 100644 index 0000000..8e43887 --- /dev/null +++ b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/WelcomeModel.java @@ -0,0 +1,46 @@ +/* + * 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.viewer.wicket.model.models; + +/** + * Model providing welcome text. + */ +public class WelcomeModel extends ModelAbstract<String> { + + private static final long serialVersionUID = 1L; + + public WelcomeModel(final String message) { + setObject(message); + } + + @Override + protected String load() { + return getObject(); + } + + @Override + public void setObject(final String message) { + if(message == null) { + return; + } + super.setObject(message); + } + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/WicketComponentUtils.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/WicketComponentUtils.java b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/WicketComponentUtils.java new file mode 100644 index 0000000..1fba4ed --- /dev/null +++ b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/WicketComponentUtils.java @@ -0,0 +1,57 @@ +/** + * 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.viewer.wicket.model.models; + +import org.apache.wicket.Component; +import org.apache.wicket.Page; +import org.apache.wicket.markup.renderStrategy.DeepChildFirstVisitor; +import org.apache.wicket.util.visit.IVisit; + +public class WicketComponentUtils { + + public WicketComponentUtils(){} + + /** + * Locates a component implementing the required class on the same page as the supplied component. + */ + public static <T> T getFrom(Component component, final Class<T> cls) { + return getFrom(component.getPage(), cls); + } + + /** + * Locates a component implementing the required class on the supplied page. + */ + public static <T> T getFrom(Page page, final Class<T> cls) { + final Object[] pComponent = new Object[1]; + page.visitChildren(new DeepChildFirstVisitor() { + @Override + public void component(Component component, IVisit<Void> visit) { + if(cls.isAssignableFrom(component.getClass())) { + pComponent[0] = component; + visit.stop(); + } + } + @Override + public boolean preCheck(Component component) { + return false; + } + }); + + return (T) pComponent[0]; + } + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/MementoFunctions.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/MementoFunctions.java b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/MementoFunctions.java new file mode 100644 index 0000000..45cfd33 --- /dev/null +++ b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/MementoFunctions.java @@ -0,0 +1,104 @@ +/* + * 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.viewer.wicket.model.util; + +import com.google.common.base.Function; + +import org.apache.isis.core.metamodel.adapter.ObjectAdapter; +import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager; +import org.apache.isis.core.metamodel.spec.ObjectSpecId; +import org.apache.isis.core.metamodel.spec.ObjectSpecification; +import org.apache.isis.core.metamodel.spec.feature.ObjectAction; +import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter; +import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation; +import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation; +import org.apache.isis.core.runtime.system.context.IsisContext; +import org.apache.isis.viewer.wicket.model.mementos.ActionMemento; +import org.apache.isis.viewer.wicket.model.mementos.ActionParameterMemento; +import org.apache.isis.viewer.wicket.model.mementos.CollectionMemento; +import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento; +import org.apache.isis.viewer.wicket.model.mementos.PropertyMemento; + +/** + * @deprecated - use {@link ObjectAdapterMemento.Functions} + */ +@Deprecated +public final class MementoFunctions { + + private MementoFunctions() { + } + + /** + * @deprecated - use {@link ObjectAdapterMemento.Functions} + */ + @Deprecated + public static Function<ObjectSpecification, ObjectSpecId> fromSpec() { + return ObjectAdapterMemento.Functions.fromSpec(); + } + + /** + * @deprecated - use {@link ObjectAdapterMemento.Functions} + */ + @Deprecated + public static Function<OneToOneAssociation, PropertyMemento> fromProperty() { + return ObjectAdapterMemento.Functions.fromProperty(); + } + + /** + * @deprecated - use {@link ObjectAdapterMemento.Functions} + */ + @Deprecated + public static Function<OneToManyAssociation, CollectionMemento> fromCollection() { + return ObjectAdapterMemento.Functions.fromCollection(); + } + + /** + * @deprecated - use {@link ObjectAdapterMemento.Functions} + */ + @Deprecated + public static Function<ObjectAction, ActionMemento> fromAction() { + return ObjectAdapterMemento.Functions.fromAction(); + } + + /** + * @deprecated - use {@link ObjectAdapterMemento.Functions} + */ + @Deprecated + public static Function<ObjectActionParameter, ActionParameterMemento> fromActionParameter() { + return ObjectAdapterMemento.Functions.fromActionParameter(); + } + + /** + * @deprecated - use {@link ObjectAdapterMemento.Functions} + */ + @Deprecated + public static Function<Object, ObjectAdapterMemento> fromPojo(final AdapterManager adapterManager) { + return ObjectAdapterMemento.Functions.fromPojo(adapterManager); + } + + /** + * @deprecated - use {@link ObjectAdapterMemento.Functions} + */ + @Deprecated + public static Function<ObjectAdapter, ObjectAdapterMemento> fromAdapter() { + return ObjectAdapterMemento.Functions.fromAdapter(); + } + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/ObjectAdapterFunctions.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/ObjectAdapterFunctions.java b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/ObjectAdapterFunctions.java new file mode 100644 index 0000000..7700e04 --- /dev/null +++ b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/ObjectAdapterFunctions.java @@ -0,0 +1,62 @@ +/* + * 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.viewer.wicket.model.util; + +import com.google.common.base.Function; + +import org.apache.isis.core.metamodel.adapter.ObjectAdapter; +import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager; +import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking; +import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento; + +/** + * @deprecated - use {@link ObjectAdapter.Functions} or {@link ObjectAdapterMemento.Functions} + */ +@Deprecated +public final class ObjectAdapterFunctions { + + private ObjectAdapterFunctions() { + } + + /** + * @deprecated - use {@link ObjectAdapter.Functions} + */ + @Deprecated + public static Function<Object, ObjectAdapter> fromPojo(final AdapterManager adapterManager) { + return ObjectAdapter.Functions.adapterForUsing(adapterManager); + } + + /** + * @deprecated - use {@link ObjectAdapterMemento.Functions} + */ + @Deprecated + public static Function<ObjectAdapterMemento, ObjectAdapter> fromMemento(final ConcurrencyChecking concurrencyChecking) { + return ObjectAdapterMemento.Functions.fromMemento(concurrencyChecking); + } + + /** + * @deprecated - use {@link ObjectAdapterMemento.Functions} + */ + @Deprecated + public static Function<ObjectAdapter, ObjectAdapterMemento> toMemento() { + return ObjectAdapterMemento.Functions.toMemento(); + } + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/OidMatchers.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/OidMatchers.java b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/OidMatchers.java new file mode 100644 index 0000000..7904a35 --- /dev/null +++ b/core/viewer-wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/OidMatchers.java @@ -0,0 +1,51 @@ +/* + * 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.viewer.wicket.model.util; + +import org.hamcrest.Matcher; + +import org.apache.isis.core.metamodel.adapter.oid.Oid; + +/** + * @deprecated - use {@link Oid.Matchers} + */ +@Deprecated +public final class OidMatchers { + + private OidMatchers() { + } + + /** + * @deprecated - use {@link Oid.Matchers} + */ + @Deprecated + public static Matcher<Oid> isTransient() { + return Oid.Matchers.isTransient(); + } + + /** + * @deprecated - use {@link Oid.Matchers} + */ + @Deprecated + public static Matcher<Oid> isPersistent() { + return Oid.Matchers.isPersistent(); + } + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ActionModelTest.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ActionModelTest.java b/core/viewer-wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ActionModelTest.java new file mode 100644 index 0000000..f7b5baa --- /dev/null +++ b/core/viewer-wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ActionModelTest.java @@ -0,0 +1,40 @@ +/* + * 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.viewer.wicket.model.models; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; + +import java.util.Map; + +import org.junit.Test; + +public class ActionModelTest { + + @Test + public void whenParseThenParses() throws Exception { + final Map.Entry<Integer, String> parsed = ActionModel.parse("3=OBJECT_OID:123"); + assertThat(parsed, is(not(nullValue()))); + assertThat(parsed.getKey(), is(3)); + assertThat(parsed.getValue(), is("OBJECT_OID:123")); + } +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/LowestCommonSuperclassClosureTest.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/LowestCommonSuperclassClosureTest.java b/core/viewer-wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/LowestCommonSuperclassClosureTest.java new file mode 100644 index 0000000..08205b2 --- /dev/null +++ b/core/viewer-wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/LowestCommonSuperclassClosureTest.java @@ -0,0 +1,67 @@ +/* + * 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.viewer.wicket.model.models; + +import static org.junit.Assert.assertThat; + +import java.util.List; + +import com.google.common.collect.Lists; + +import org.junit.Test; + +import org.apache.isis.core.commons.lang.IterableExtensions; +import org.apache.isis.core.commons.matchers.IsisMatchers; + +public class LowestCommonSuperclassClosureTest { + + static class Animal {} + static class Mineral {} + static class Vegetable {} + static class Mammal extends Animal {} + static class Lion extends Mammal {} + + @Test + public void nothingInCommon() throws Exception { + assertLowestCommonOfListIs(listOf(Animal.class, Mineral.class, Vegetable.class), Object.class); + } + + @Test + public void superclassInCommon() throws Exception { + assertLowestCommonOfListIs(listOf(Animal.class, Mammal.class), Animal.class); + } + + @Test + public void subclassInCommon() throws Exception { + assertLowestCommonOfListIs(listOf(Lion.class, Lion.class), Lion.class); + } + + private static void assertLowestCommonOfListIs(List<Class<? extends Object>> list, Class<?> expected) { + EntityCollectionModel.LowestCommonSuperclassClosure closure = new EntityCollectionModel.LowestCommonSuperclassClosure(); + IterableExtensions.fold(list, closure); + assertThat(closure.getLowestCommonSuperclass(), IsisMatchers.classEqualTo(expected)); + } + + private static List<Class<? extends Object>> listOf(Class<?>... classes) { + return Lists.newArrayList(classes); + } + + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ModelAbstractTest.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ModelAbstractTest.java b/core/viewer-wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ModelAbstractTest.java new file mode 100644 index 0000000..4655239 --- /dev/null +++ b/core/viewer-wicket/model/src/test/java/org/apache/isis/viewer/wicket/model/models/ModelAbstractTest.java @@ -0,0 +1,170 @@ +/** + * 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.viewer.wicket.model.models; + +import java.util.Map; +import org.apache.wicket.Component; +import org.apache.wicket.MarkupContainer; +import org.apache.wicket.model.IModel; +import org.jmock.Expectations; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2; +import org.apache.isis.viewer.wicket.model.hints.UiHintPathSignificant; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.junit.Assert.assertThat; + +public class ModelAbstractTest { + + @Rule + public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(JUnitRuleMockery2.Mode.INTERFACES_AND_CLASSES); + + ModelAbstract<String> target; + + static class UiHintPathSignificantComponent extends Component implements UiHintPathSignificant { + public UiHintPathSignificantComponent(String id) { + super(id); + } + + public UiHintPathSignificantComponent(String id, IModel<?> model) { + super(id, model); + } + + @Override + protected void onRender() { + } + } + + static class UiHintPathSignificantMarkupContainer extends MarkupContainer implements UiHintPathSignificant { + public UiHintPathSignificantMarkupContainer(String id) { + super(id); + } + + public UiHintPathSignificantMarkupContainer(String id, IModel<?> model) { + super(id, model); + } + + @Override + protected void onRender() { + } + } + + MarkupContainer mockParent; + Component mockComponent1; + Component mockComponent2; + + @Before + public void setUp() throws Exception { + target = new ModelAbstract<String>("foo"){ + @Override + protected String load() { + return null; + } + }; + + mockParent = context.mock(UiHintPathSignificantMarkupContainer.class, "parent"); + mockComponent1 = context.mock(UiHintPathSignificantComponent.class, "component1"); + mockComponent2 = context.mock(UiHintPathSignificantComponent.class, "component2"); + + context.checking(new Expectations() {{ + allowing(mockParent).getId(); + will(returnValue("parent")); + + allowing(mockComponent1).getId(); + will(returnValue("id1")); + + allowing(mockComponent2).getId(); + will(returnValue("id2")); + + ignoring(mockComponent1); + ignoring(mockComponent2); + + }}); + + mockComponent1.setParent(mockParent); + mockComponent2.setParent(mockParent); + } + + public static class Hints extends ModelAbstractTest { + + @Test + public void empty() throws Exception { + assertThat(target.getHint(mockComponent1, "key1"), is(nullValue())); + } + + @Test + public void single() throws Exception { + target.setHint(mockComponent1, "key1", "value1"); + assertThat(target.getHint(mockComponent1, "key1"), is("value1")); + } + + @Test + public void clear() throws Exception { + target.setHint(mockComponent1, "key1", "value1"); + assertThat(target.getHint(mockComponent1, "key1"), is("value1")); + target.clearHint(mockComponent1, "key1"); + assertThat(target.getHint(mockComponent1, "key1"), is(nullValue())); + } + + @Test + public void setToNull() throws Exception { + target.setHint(mockComponent1, "key1", "value1"); + assertThat(target.getHint(mockComponent1, "key1"), is("value1")); + target.setHint(mockComponent1, "key1", null); + assertThat(target.getHint(mockComponent1, "key1"), is(nullValue())); + } + + @Test + public void multipleKeys() throws Exception { + target.setHint(mockComponent1, "key1", "value1"); + target.setHint(mockComponent1, "key2", "value2"); + assertThat(target.getHint(mockComponent1, "key1"), is("value1")); + assertThat(target.getHint(mockComponent1, "key2"), is("value2")); + } + + @Test + public void multipleComponents() throws Exception { + target.setHint(mockComponent1, "key", "valueA"); + target.setHint(mockComponent2, "key", "valueB"); + assertThat(target.getHint(mockComponent1, "key"), is("valueA")); + assertThat(target.getHint(mockComponent2, "key"), is("valueB")); + } + + @Test + public void smoke() throws Exception { + target.setHint(mockComponent1, "X", "1.X"); + target.setHint(mockComponent1, "A", "1.A"); + target.setHint(mockComponent1, "B", "1.B"); + target.setHint(mockComponent1, "C", "1.C"); + target.setHint(mockComponent2, "X", "2.X"); + target.setHint(mockComponent2, "P", "2.P"); + target.setHint(mockComponent2, "Q", "2.Q"); + target.setHint(mockComponent2, "R", "2.R"); + + final Map<String, String> hints = target.getHints(); + assertThat(hints.size(), is(8)); + assertThat(hints.get("id1-X"), is("1.X")); + assertThat(hints.get("id2-X"), is("2.X")); + assertThat(hints.get("id1-B"), is("1.B")); + assertThat(hints.get("id2-R"), is("2.R")); + } + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/pom.xml ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/pom.xml b/core/viewer-wicket/pom.xml new file mode 100644 index 0000000..0e61f86 --- /dev/null +++ b/core/viewer-wicket/pom.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.isis.core</groupId> + <artifactId>isis</artifactId> + <version>1.8.0-SNAPSHOT</version> + </parent> + + <groupId>org.apache.isis.viewer</groupId> + <artifactId>isis-viewer-wicket</artifactId> + + <name>Isis Wicket Viewer</name> + + <packaging>pom</packaging> + + <properties> + <siteBaseDir>..</siteBaseDir> + <relativeUrl /> + + </properties> + + <!-- used in Site generation for relative references. --> + <url>http://isis.apache.org/${relativeUrl}</url> + + <modules> + <module>applib</module> + <module>model</module> + <module>ui</module> + <module>impl</module> + </modules> + + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>net.alchim31.maven</groupId> + <artifactId>yuicompressor-maven-plugin</artifactId> + <version>1.5.0</version> + <configuration> + <statistics>true</statistics> + <jswarn>false</jswarn> + <suffix>.min</suffix> + <excludes> + <exclude>**/moment.js</exclude> + <exclude>**/moment.min.js</exclude> + <exclude>**/bootstrap-datetimepicker.js</exclude> + <exclude>**/bootstrap-datetimepicker.min.js</exclude> + <exclude>**/bootstrap-growl.js</exclude> + <exclude>**/bootstrap-growl.min.js</exclude> + </excludes> + </configuration> + <executions> + <execution> + <goals> + <goal>compress</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </pluginManagement> + </build> + +</project> http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/src/main/appended-resources/supplemental-models.xml ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/src/main/appended-resources/supplemental-models.xml b/core/viewer-wicket/src/main/appended-resources/supplemental-models.xml new file mode 100644 index 0000000..b839240 --- /dev/null +++ b/core/viewer-wicket/src/main/appended-resources/supplemental-models.xml @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- 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. --> +<supplementalDataModels xmlns="http://maven.apache.org/supplemental-model/1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/supplemental-model/1.0.0 http://maven.apache.org/xsd/supplemental-model-1.0.0.xsd"> + + <supplement> + <project> + <groupId>aopalliance</groupId> + <artifactId>aopalliance</artifactId> + <version>1.0</version> + <licenses> + <license> + <name>Public Domain</name> + </license> + </licenses> + </project> + </supplement> + + <supplement> + <project> + <groupId>dom4j</groupId> + <artifactId>dom4j</artifactId> + <version>1.6.1</version> + <licenses> + <license> + <name>BSD License</name> + <url>http://dom4j.sourceforge.net/dom4j-1.6.1/license.html</url> + <distribution>repo</distribution> + </license> + </licenses> + </project> + </supplement> + + + <supplement> + <project> + <groupId>org.datanucleus</groupId> + <artifactId>datanucleus-jdo-query</artifactId> + <version>3.0.2</version> + <licenses> + <license> + <name>The Apache Software License, Version 2.0</name> + <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url> + </license> + </licenses> + </project> + </supplement> + + <supplement> + <project> + <groupId>javax.transaction</groupId> + <artifactId>transaction-api</artifactId> + <version>1.1</version> + <name>Java Transaction API (JTA)</name> + <organization> + <name>Oracle Corp</name> + <url>http://www.oracle.com/</url> + </organization> + <licenses> + <license> + <name>Common Development and Distribution License (CDDL) v1.0</name> + <url>https://glassfish.java.net/public/CDDLv1.0.html</url> + </license> + </licenses> + </project> + </supplement> + + <!-- + <supplement> + <project> + <groupId>org.datanucleus</groupId> + <artifactId>datanucleus-jodatime</artifactId> + <version>3.1.1</version> + <licenses> + <license> + <name>The Apache Software License, Version 2.0</name> + <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url> + </license> + </licenses> + </project> + </supplement> + + <supplement> + <project> + <groupId>org.scannotation</groupId> + <artifactId>scannotation</artifactId> + <version>1.0.3</version> + <licenses> + <license> + <name>The Apache Software License, Version 2.0</name> + <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url> + <distribution>repo</distribution> + </license> + </licenses> + </project> + </supplement> + + <supplement> + <project> + <groupId>net.jcip</groupId> + <artifactId>jcip-annotations</artifactId> + <version>1.0</version> + <licenses> + <license> + <name>Creative Commons Attribution 2.5 License</name> + <url>http://creativecommons.org/licenses/by/2.5/</url> + <distribution>repo</distribution> + </license> + </licenses> + </project> + </supplement> + + + <supplement> + <project> + <groupId>xalan</groupId> + <artifactId>xalan</artifactId> + <version>2.7.0</version> + <licenses> + <license> + <name>The Apache Software License, Version 2.0</name> + <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url> + <distribution>repo</distribution> + </license> + </licenses> + </project> + </supplement> + --> + + +</supplementalDataModels> http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/ui/pom.xml ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/ui/pom.xml b/core/viewer-wicket/ui/pom.xml new file mode 100644 index 0000000..bca5b7d --- /dev/null +++ b/core/viewer-wicket/ui/pom.xml @@ -0,0 +1,152 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.isis.viewer</groupId> + <artifactId>isis-viewer-wicket</artifactId> + <version>1.8.0-SNAPSHOT</version> + </parent> + + <artifactId>isis-viewer-wicket-ui</artifactId> + <name>Isis Wicket Viewer UI Components</name> + + <properties> + <siteBaseDir>..</siteBaseDir> + <relativeUrl>ui/</relativeUrl> + </properties> + + <!-- used in Site generation for relative references. --> + <url>http://isis.apache.org/${relativeUrl}</url> + + <build> + <resources> + <resource> + <filtering>false</filtering> + <directory>src/main/resources</directory> + </resource> + <resource> + <filtering>false</filtering> + <directory>src/main/java</directory> + <includes> + <include>**</include> + </includes> + <excludes> + <exclude>**/*.java</exclude> + </excludes> + </resource> + </resources> + <plugins> + <plugin> + <groupId>net.alchim31.maven</groupId> + <artifactId>yuicompressor-maven-plugin</artifactId> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>org.apache.isis.viewer</groupId> + <artifactId>isis-viewer-wicket-model</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.isis.core</groupId> + <artifactId>isis-core-metamodel</artifactId> + </dependency> + <dependency> + <groupId>org.apache.isis.core</groupId> + <artifactId>isis-core-unittestsupport</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.wicket</groupId> + <artifactId>wicket-core</artifactId> + </dependency> + <dependency> + <groupId>org.apache.wicket</groupId> + <artifactId>wicket-extensions</artifactId> + </dependency> + <dependency> + <groupId>org.apache.wicket</groupId> + <artifactId>wicket-auth-roles</artifactId> + </dependency> + <dependency> + <groupId>org.apache.wicket</groupId> + <artifactId>wicket-guice</artifactId> + </dependency> + <dependency> + <groupId>com.vaynberg.wicket.select2</groupId> + <artifactId>wicket-select2</artifactId> + </dependency> + + <dependency> + <groupId>org.webjars</groupId> + <artifactId>select2</artifactId> + </dependency> + + <dependency> + <groupId>org.webjars</groupId> + <artifactId>jquery-ui</artifactId> + </dependency> + + <!-- WEBJARS --> + <dependency> + <groupId>de.agilecoders.wicket.webjars</groupId> + <artifactId>wicket-webjars</artifactId> + </dependency> + + <dependency> + <groupId>de.agilecoders.wicket</groupId> + <artifactId>wicket-bootstrap-core</artifactId> + </dependency> + + <dependency> + <groupId>de.agilecoders.wicket</groupId> + <artifactId>wicket-bootstrap-extensions</artifactId> + </dependency> + + <dependency> + <groupId>de.agilecoders.wicket</groupId> + <artifactId>wicket-bootstrap-themes</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-servlet_2.5_spec</artifactId> + <scope>provided</scope> + </dependency> + + <!-- LOGGING DEPENDENCIES - LOG4J --> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </dependency> + + </dependencies> +</project> http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/ui/src/main/java/images/Images.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/ui/src/main/java/images/Images.java b/core/viewer-wicket/ui/src/main/java/images/Images.java new file mode 100644 index 0000000..f1e6fb0 --- /dev/null +++ b/core/viewer-wicket/ui/src/main/java/images/Images.java @@ -0,0 +1,33 @@ +/* + * 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 images; + +import org.apache.wicket.request.resource.PackageResource; + +/** + * This is a bit of a hack, but the Isis convention is to plonk all the images + * in an images package. This empty class allows Wicket to pick them up as + * {@link PackageResource}s. + */ +public final class Images { + + private Images() { + } +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/CollectionContentsAsFactory.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/CollectionContentsAsFactory.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/CollectionContentsAsFactory.java new file mode 100644 index 0000000..440b0ff --- /dev/null +++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/CollectionContentsAsFactory.java @@ -0,0 +1,49 @@ +/* + * 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.viewer.wicket.ui; + +import org.apache.wicket.model.IModel; + +/** + * <p> + * An interface for all {@link org.apache.isis.viewer.wicket.ui.ComponentFactory component factories} + * (e.g. CollectionContentAsXyzFactory-ies) which want to provide specific title and CSS class(es) + * for their representation in {@link org.apache.isis.viewer.wicket.ui.components.collectioncontents.multiple.CollectionContentsMultipleViewsPanel}. + * </p> + * <p> + * If the {@link org.apache.isis.viewer.wicket.ui.ComponentFactory} doesn't implement this interface or the implementation + * of any of its methods return {@code null} then {@link ComponentFactory#getName()} will be used as title and its + * {@link org.apache.isis.core.commons.lang.StringExtensions#asLowerDashed(java.lang.String) dashed representation} + * as CSS class for the optional image. + * </p> + */ +public interface CollectionContentsAsFactory { + + /** + * @return A model that will be used as a label for the "View as" dropdown for "collection contents as" + * component factories + */ + IModel<String> getTitleLabel(); + + /** + * @return A model that will be used as a CSS class for the icon/image next to "View as" dropdown + * for "collection contents as" component factories + */ + IModel<String> getCssClass(); +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactory.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactory.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactory.java new file mode 100644 index 0000000..e52ad7a --- /dev/null +++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactory.java @@ -0,0 +1,107 @@ +/* + * 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.viewer.wicket.ui; + +import java.io.Serializable; + +import org.apache.wicket.Component; +import org.apache.wicket.model.IModel; +import org.apache.wicket.request.resource.CssResourceReference; + +import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistry; + +/** + * Creates {@link Component}s of a specified {@link ComponentType}, optionally + * {@link #appliesTo(ComponentType, IModel) dependent on} the provided + * {@link IModel model}. + * + * <p> + * This interface is at the very heart of the Wicket Objects' model, being an + * usage of the chain-of-responsibility design pattern. The available + * {@link ComponentFactory}s are registered through + * {@link ComponentFactoryRegistry} (bootstrapped from the + * <tt>IsisWicketApplication</tt>); various adapters make it easy to lookup + * {@link Component}s from this registry. + */ +public interface ComponentFactory extends Serializable { + + /** + * The {@link ComponentType} with which this component factory has been + * registered. + */ + ComponentType getComponentType(); + + public enum ApplicationAdvice { + APPLIES(true, false), + APPLIES_EXCLUSIVELY(true, true), + DOES_NOT_APPLY(false, false); + private final boolean applies; + private final boolean exclusively; + + private ApplicationAdvice(final boolean applies, final boolean exclusively) { + this.applies = applies; + this.exclusively = exclusively; + } + + public boolean applies() { + return applies; + } + + /** + * Whether no other {@link ComponentFactory}s should apply (ie stop + * searching for other views). + */ + public boolean exclusively() { + return exclusively; + } + + public static final ApplicationAdvice appliesIf(final boolean b) { + return b ? ApplicationAdvice.APPLIES : ApplicationAdvice.DOES_NOT_APPLY; + } + } + + /** + * Whether the {@link Component} created by this factory applies to the + * specified {@link ComponentType} and {@link IModel}. + */ + ApplicationAdvice appliesTo(ComponentType componentType, IModel<?> model); + + /** + * Creates component, with id being derived from the + * {@link #getComponentType() component type} for this factory. + * + * @param model + * @return + */ + Component createComponent(IModel<?> model); + + /** + * Creates component, with specified id. + */ + Component createComponent(String id, IModel<?> model); + + /** + * Used for rendering in drop-downs. + */ + String getName(); + + CssResourceReference getCssResourceReference(); + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactoryAbstract.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactoryAbstract.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactoryAbstract.java new file mode 100644 index 0000000..e018a74 --- /dev/null +++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactoryAbstract.java @@ -0,0 +1,115 @@ +/* + * 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.viewer.wicket.ui; + +import org.apache.wicket.Component; +import org.apache.wicket.model.IModel; +import org.apache.wicket.request.resource.CssResourceReference; + +import org.apache.isis.viewer.wicket.ui.panels.PanelUtil; + +/** + * Adapter implementation for {@link ComponentFactory}. + */ +public abstract class ComponentFactoryAbstract implements ComponentFactory { + + private static final long serialVersionUID = 1L; + + private final ComponentType componentType; + private final String name; + + private final Class<?> componentClass; + + public ComponentFactoryAbstract(final ComponentType componentType) { + this(componentType, null, null); + } + + public ComponentFactoryAbstract(final ComponentType componentType, final String name) { + this(componentType, name, null); + } + + public ComponentFactoryAbstract(final ComponentType componentType, @SuppressWarnings("rawtypes") Class componentClass) { + this(componentType, null, componentClass); + } + + public ComponentFactoryAbstract(final ComponentType componentType, final String name, @SuppressWarnings("rawtypes") Class componentClass) { + this.componentType = componentType; + this.name = name != null ? name : getClass().getSimpleName(); + if(componentClass != null && ComponentFactory.class.isAssignableFrom(componentClass)) { + throw new IllegalArgumentException("specified a ComponentFactory as a componentClass... you probably meant the component instead? componentClass = " + componentClass.getName()); + } + this.componentClass = componentClass; + } + + @Override + public ComponentType getComponentType() { + return componentType; + } + + /** + * Applies if {@link #getComponentType()} matches; disregards the provided + * {@link IModel}. + * + * @see #appliesTo(IModel) + */ + @Override + public final ApplicationAdvice appliesTo(final ComponentType componentType, final IModel<?> model) { + if (componentType != getComponentType()) { + return ApplicationAdvice.DOES_NOT_APPLY; + } + return appliesTo(model); + } + + /** + * Hook for subclasses to check the {@link IModel}. + */ + protected abstract ApplicationAdvice appliesTo(IModel<?> model); + + protected final ApplicationAdvice appliesIf(final boolean b) { + return ApplicationAdvice.appliesIf(b); + } + + /** + * Convenience for subclasses to call from {@link #appliesTo(IModel)} + */ + protected final ApplicationAdvice appliesExclusivelyIf(final boolean b) { + return b ? ApplicationAdvice.APPLIES_EXCLUSIVELY : ApplicationAdvice.DOES_NOT_APPLY; + } + + @Override + public final Component createComponent(final IModel<?> model) { + return createComponent(getComponentType().toString(), model); + } + + @Override + public abstract Component createComponent(String id, IModel<?> model); + + @Override + public String getName() { + return name; + } + + @Override + public CssResourceReference getCssResourceReference() { + return PanelUtil.cssResourceReferenceFor(componentClass); + } + + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentType.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentType.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentType.java new file mode 100644 index 0000000..70281cf --- /dev/null +++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentType.java @@ -0,0 +1,180 @@ +/* + * 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.viewer.wicket.ui; + +import org.apache.wicket.Component; + +import org.apache.isis.core.commons.lang.StringExtensions; + +/** + * Enumerates the different types of {@link Component}s that can be constructed + * using {@link ComponentFactory}. + * + * <p> + * Some are fine-grained (such as {@link ComponentType#SCALAR_NAME_AND_VALUE}, a + * panel to represent a single scalar property or parameter), but others are + * somewhat larger (such as {@link ComponentType#ENTITY}, representing an + * entity, with its actions, properties and collections). + */ +public enum ComponentType { + + + /** + * About page text. + */ + ABOUT, + /** + * Welcome page text. + */ + WELCOME, + /** + * List of services and their actions. + * + * <p> + * Could be rendered using a JavaScript or DHTML menu, an accordion, or a + * tree view. + */ + SERVICE_ACTIONS, + /** + * A single domain entity. + */ + ENTITY, + /** + * Icon and title for a single entity. + */ + ENTITY_ICON_AND_TITLE, + /** + * Icon, title and a copy link for a single entity. + */ + ENTITY_ICON_TITLE_AND_COPYLINK, + /** + * Title, icon and action list for a single entity. + */ + ENTITY_SUMMARY, + /** + * The set of properties for a single entity. + */ + ENTITY_PROPERTIES, + /** + * The set of collections of a single entity, designed to be standalone outside of a form. + * + * <p> + * compare with {@value #ENTITY_COLLECTIONS}. + */ + ENTITY_COLLECTIONS, + /** + * A single standalone value, as might be returned from an action. + */ + VALUE, + /** + * The name and value of a single property or parameter, ie a scalar. + */ + SCALAR_NAME_AND_VALUE, + /** + * The name and contents of a single collection of an entity; + * {@link Component}s are expected to use {@link #COLLECTION_CONTENTS} to + * actually render the contents. + */ + COLLECTION_NAME_AND_CONTENTS, + /** + * The parameter form (dialog box) of an action. + */ + PARAMETERS, + /** + * Info details for an action, eg to display the target, a resubmit button, + * any description or help text, and so on. + */ + ACTION_INFO, + /** + * Used to display the parameters of an action. + */ + ACTION_PROMPT, + /** + * Top-level component for rendering a standalone collection (ie as returned by + * an action). + */ + STANDALONE_COLLECTION, + /** + * Bookmarked link to invoke an action + */ + ACTION_LINK, + /** + * A collection of entities (the value of) + */ + COLLECTION_CONTENTS, + /** + * A link to an entity. + */ + ENTITY_LINK, + /** + * A collection of entities, from an action, but none returned. + */ + EMPTY_COLLECTION, + /** + * A void result from an action. + */ + VOID_RETURN, + /** + * A list of {@link IsisModel}s, rendered as a list of links. + */ + BOOKMARKED_PAGES, + /** + * Place holder for a component used to represent an unknown model; + * not used for matching, since the {@link ComponentFactory} implementation + * acts as a fallback whenever a more suitable factory cannot be located. + */ + UNKNOWN, + + /** + * The header (navigation bar) of the page + */ + HEADER, + + /** + * The footer of the page + */ + FOOTER; + + /** + * Returns the {@link #name()} formatted as + * {@link org.apache.isis.core.commons.lang.StringExtensions#toCamelCase(String) case}. + * + * <p> + * For example, <tt>OBJECT_EDIT</tt> becomes <tt>objectEdit</tt>. + */ + @Override + public String toString() { + return getWicketId(); + } + + public String getWicketId() { + return StringExtensions.toCamelCase(name()); + } + + public static ComponentType lookup(final String id) { + for (final ComponentType componentType : values()) { + if (componentType.getWicketId().equals(id)) { + return componentType; + } + } + return null; + } + +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/HeaderContributorProvider.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/HeaderContributorProvider.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/HeaderContributorProvider.java new file mode 100644 index 0000000..fd9663b --- /dev/null +++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/HeaderContributorProvider.java @@ -0,0 +1,27 @@ +/* + * 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.viewer.wicket.ui; + +import org.apache.wicket.markup.html.IHeaderContributor; + +// TODO unused. Remove ?! +public interface HeaderContributorProvider { + + IHeaderContributor getHeaderContributor(); +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponse.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponse.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponse.java new file mode 100644 index 0000000..ad5bbf5 --- /dev/null +++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponse.java @@ -0,0 +1,92 @@ +/** + * 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.viewer.wicket.ui.actionresponse; + +import java.net.URL; + +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.request.IRequestHandler; + +import org.apache.isis.viewer.wicket.ui.pages.PageAbstract; + +/** + * The response to provide as a result of interpreting the response; + * either to show a {@link #toPage(PageAbstract) page}, or to {@link #withHandler(IRequestHandler) redirect} to a + * handler (eg a download). + */ +public class ActionResultResponse { + + private final ActionResultResponseHandlingStrategy handlingStrategy; + private final IRequestHandler handler; + private final PageAbstract page; + private final AjaxRequestTarget target; + private final URL url; + + public static ActionResultResponse withHandler(IRequestHandler handler) { + return new ActionResultResponse( + ActionResultResponseHandlingStrategy.SCHEDULE_HANDLER, handler, null, null, null); + } + public static ActionResultResponse toPage(PageAbstract page) { + return new ActionResultResponse( + ActionResultResponseHandlingStrategy.REDIRECT_TO_PAGE, null, page, null, null); + } + public static ActionResultResponse openUrlInBrowser(final AjaxRequestTarget target, final URL url) { + return new ActionResultResponse( + ActionResultResponseHandlingStrategy.OPEN_URL_IN_BROWSER, null, null, target, url); + } + private ActionResultResponse( + final ActionResultResponseHandlingStrategy strategy, + final IRequestHandler handler, + final PageAbstract page, + final AjaxRequestTarget target, + final URL url) { + handlingStrategy = strategy; + this.handler = handler; + this.page = page; + this.target = target; + this.url = url; + } + + public ActionResultResponseHandlingStrategy getHandlingStrategy() { + return handlingStrategy; + } + + /** + * Populated only if {@link #getHandlingStrategy() handling strategy} is {@link ActionResultResponseHandlingStrategy#SCHEDULE_HANDLER} + */ + public IRequestHandler getHandler() { + return handler; + } + /** + * Populated only if {@link #getHandlingStrategy() handling strategy} is {@link ActionResultResponseHandlingStrategy#REDIRECT_TO_PAGE} + */ + public PageAbstract getToPage() { + return page; + } + /** + * Populated only if {@link #getHandlingStrategy() handling strategy} is {@link ActionResultResponseHandlingStrategy#OPEN_URL_IN_BROWSER} + */ + public AjaxRequestTarget getTarget() { + return target; + } + /** + * Populated only if {@link #getHandlingStrategy() handling strategy} is {@link ActionResultResponseHandlingStrategy#OPEN_URL_IN_BROWSER} + */ + public URL getUrl() { + return url; + } +} http://git-wip-us.apache.org/repos/asf/isis/blob/d84c6609/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponseHandlingStrategy.java ---------------------------------------------------------------------- diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponseHandlingStrategy.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponseHandlingStrategy.java new file mode 100644 index 0000000..3bc6e65 --- /dev/null +++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponseHandlingStrategy.java @@ -0,0 +1,139 @@ +/** + * 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.viewer.wicket.ui.actionresponse; + +import java.net.URL; + +import org.apache.isis.core.runtime.system.context.IsisContext; +import org.apache.isis.viewer.wicket.model.models.VoidModel; +import org.apache.isis.viewer.wicket.ui.pages.voidreturn.VoidReturnPage; +import org.apache.wicket.Component; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.behavior.AbstractAjaxBehavior; +import org.apache.wicket.request.Url; +import org.apache.wicket.request.cycle.RequestCycle; +import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler; +import org.apache.wicket.request.resource.ContentDisposition; +import org.apache.wicket.util.resource.IResourceStream; +import org.apache.wicket.util.time.Duration; + +public enum ActionResultResponseHandlingStrategy { + REDIRECT_TO_VOID { + @Override + public void handleResults(Component component, ActionResultResponse resultResponse) { + component.setResponsePage(new VoidReturnPage(new VoidModel())); + } + }, + REDIRECT_TO_PAGE { + @Override + public void handleResults(final Component component, final ActionResultResponse resultResponse) { + // force any changes in state etc to happen now prior to the redirect; + // in the case of an object being returned, this should cause our page mementos + // (eg EntityModel) to hold the correct state. I hope. + IsisContext.getTransactionManager().flushTransaction(); + + // "redirect-after-post" + component.setResponsePage(resultResponse.getToPage()); + } + }, + SCHEDULE_HANDLER { + @Override + public void handleResults(final Component component, final ActionResultResponse resultResponse) { + RequestCycle requestCycle = component.getRequestCycle(); + AjaxRequestTarget target = requestCycle.find(AjaxRequestTarget.class); + if (target == null) { + // normal (non-Ajax) request => just stream the Lob to the browser + requestCycle.scheduleRequestHandlerAfterCurrent(resultResponse.getHandler()); + } else { + // Ajax request => respond with a redirect to be able to stream the Lob to the client + ResourceStreamRequestHandler scheduledHandler = (ResourceStreamRequestHandler) resultResponse.getHandler(); + StreamAfterAjaxResponseBehavior streamingBehavior = new StreamAfterAjaxResponseBehavior(scheduledHandler); + component.getPage().add(streamingBehavior); + CharSequence callbackUrl = streamingBehavior.getCallbackUrl(); + target.appendJavaScript("setTimeout(\"window.location.href='" + callbackUrl + "'\", 10);"); + } + } + }, + OPEN_URL_IN_BROWSER { + @Override + public void handleResults(final Component component, final ActionResultResponse resultResponse) { + final AjaxRequestTarget target = resultResponse.getTarget(); + final URL url = resultResponse.getUrl(); + + RequestCycle requestCycle = component.getRequestCycle(); + + final String fullUrl = expanded(requestCycle, url); + target.appendJavaScript("setTimeout(function(){Wicket.Event.publish(Isis.Topic.OPEN_IN_NEW_TAB, '" + fullUrl + "');}, 100);"); + } + + }; + + public abstract void handleResults(Component component, ActionResultResponse resultResponse); + + /** + * @see #expanded(String) + */ + public static String expanded(RequestCycle requestCycle, final URL url) { + String urlStr = expanded(url); + return requestCycle.getUrlRenderer().renderFullUrl(Url.parse(urlStr)); + } + + /** + * @see #expanded(String) + */ + public static String expanded(final URL url) { + return expanded(url.toString()); + } + + /** + * very simple templating support, the idea being that "antiCache=${currentTimeMillis}" + * will be replaced automatically. + */ + public static String expanded(String urlStr) { + if(urlStr.contains("antiCache=${currentTimeMillis}")) { + urlStr = urlStr.replace("antiCache=${currentTimeMillis}", "antiCache="+System.currentTimeMillis()); + } + return urlStr; + } + + /** + * A special Ajax behavior that is used to stream the contents of a Lob after + * an Ajax request. + */ + private static class StreamAfterAjaxResponseBehavior extends AbstractAjaxBehavior { + + private final String fileName; + private final IResourceStream resourceStream; + private final Duration cacheDuration; + + public StreamAfterAjaxResponseBehavior(ResourceStreamRequestHandler scheduledHandler) { + this.fileName = scheduledHandler.getFileName(); + this.resourceStream = scheduledHandler.getResourceStream(); + this.cacheDuration = scheduledHandler.getCacheDuration(); + } + + @Override + public void onRequest() { + ResourceStreamRequestHandler handler = new ResourceStreamRequestHandler(resourceStream, fileName); + handler.setCacheDuration(cacheDuration); + handler.setContentDisposition(ContentDisposition.ATTACHMENT); + Component page = getComponent(); + page.getRequestCycle().scheduleRequestHandlerAfterCurrent(handler); + page.remove(this); + } + } +}