You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2015/09/03 14:32:35 UTC
[44/87] [abbrv] [partial] isis git commit: ISIS-1194: moving the
wicket submodules to be direct children of core;
removing the isis-viewer-wicket parent pom.
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/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/99094b7e/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/99094b7e/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/99094b7e/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/99094b7e/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);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponseType.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponseType.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponseType.java
new file mode 100644
index 0000000..62291f8
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/actionresponse/ActionResultResponseType.java
@@ -0,0 +1,202 @@
+/**
+ * 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 java.util.Collection;
+import java.util.List;
+import com.google.common.collect.Lists;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.request.IRequestHandler;
+import org.apache.isis.applib.value.Blob;
+import org.apache.isis.applib.value.Clob;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
+import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.wicket.model.models.ActionModel;
+import org.apache.isis.viewer.wicket.model.models.EntityCollectionModel;
+import org.apache.isis.viewer.wicket.model.models.ValueModel;
+import org.apache.isis.viewer.wicket.model.models.VoidModel;
+import org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage;
+import org.apache.isis.viewer.wicket.ui.pages.standalonecollection.StandaloneCollectionPage;
+import org.apache.isis.viewer.wicket.ui.pages.value.ValuePage;
+import org.apache.isis.viewer.wicket.ui.pages.voidreturn.VoidReturnPage;
+
+public enum ActionResultResponseType {
+ OBJECT {
+ @Override
+ public ActionResultResponse interpretResult(final ActionModel model, final AjaxRequestTarget target, final ObjectAdapter resultAdapter) {
+ final ObjectAdapter actualAdapter = determineActualAdapter(resultAdapter);
+ return toEntityPage(model, actualAdapter, null);
+ }
+
+ @Override
+ public ActionResultResponse interpretResult(final ActionModel model, ObjectAdapter targetAdapter, ConcurrencyException ex) {
+ return toEntityPage(model, targetAdapter, ex);
+ }
+ },
+ COLLECTION {
+ @Override
+ public ActionResultResponse interpretResult(final ActionModel actionModel, final AjaxRequestTarget target, final ObjectAdapter resultAdapter) {
+ final EntityCollectionModel collectionModel = EntityCollectionModel.createStandalone(resultAdapter);
+ // take a copy of the actionModel, because the original can get mutated (specifically: its arguments cleared)
+ final ActionModel actionModelCopy = actionModel.copy();
+ collectionModel.setActionHint(actionModelCopy);
+ return ActionResultResponse.toPage(new StandaloneCollectionPage(collectionModel));
+ }
+ },
+ VALUE {
+ @Override
+ public ActionResultResponse interpretResult(final ActionModel model, final AjaxRequestTarget target, final ObjectAdapter resultAdapter) {
+ ValueModel valueModel = new ValueModel(resultAdapter);
+ valueModel.setActionHint(model);
+ final ValuePage valuePage = new ValuePage(valueModel);
+ return ActionResultResponse.toPage(valuePage);
+ }
+ },
+ VALUE_CLOB {
+ @Override
+ public ActionResultResponse interpretResult(final ActionModel model, final AjaxRequestTarget target, final ObjectAdapter resultAdapter) {
+ final Object value = resultAdapter.getObject();
+ IRequestHandler handler = ActionModel.downloadHandler(value);
+ return ActionResultResponse.withHandler(handler);
+ }
+ },
+ VALUE_BLOB {
+ @Override
+ public ActionResultResponse interpretResult(final ActionModel model, final AjaxRequestTarget target, final ObjectAdapter resultAdapter) {
+ final Object value = resultAdapter.getObject();
+ IRequestHandler handler = ActionModel.downloadHandler(value);
+ return ActionResultResponse.withHandler(handler);
+ }
+ },
+ VALUE_URL_AJAX {
+ @Override
+ public ActionResultResponse interpretResult(final ActionModel model, final AjaxRequestTarget target, final ObjectAdapter resultAdapter) {
+ final URL url = (URL)resultAdapter.getObject();
+ return ActionResultResponse.openUrlInBrowser(target, url);
+ }
+
+ },
+ VALUE_URL_NOAJAX {
+ @Override
+ public ActionResultResponse interpretResult(final ActionModel model, final AjaxRequestTarget target, final ObjectAdapter resultAdapter) {
+ // open URL server-side redirect
+ final Object value = resultAdapter.getObject();
+ IRequestHandler handler = ActionModel.redirectHandler(value);
+ return ActionResultResponse.withHandler(handler);
+ }
+
+ },
+ VOID {
+ @Override
+ public ActionResultResponse interpretResult(final ActionModel model, final AjaxRequestTarget target, final ObjectAdapter resultAdapter) {
+ final VoidModel voidModel = new VoidModel();
+ voidModel.setActionHint(model);
+ return ActionResultResponse.toPage(new VoidReturnPage(voidModel));
+ }
+ };
+
+ public abstract ActionResultResponse interpretResult(ActionModel model, final AjaxRequestTarget target, ObjectAdapter resultAdapter);
+
+ /**
+ * Only overridden for {@link ActionResultResponseType#OBJECT object}
+ */
+ public ActionResultResponse interpretResult(ActionModel model, ObjectAdapter targetAdapter, ConcurrencyException ex) {
+ throw new UnsupportedOperationException("Cannot render concurrency exception for any result type other than OBJECT");
+ }
+
+ private static ObjectAdapter determineActualAdapter(final ObjectAdapter resultAdapter) {
+ if (resultAdapter.getSpecification().isNotCollection()) {
+ return resultAdapter;
+ } else {
+ // will only be a single element
+ final List<Object> pojoList = asList(resultAdapter);
+ final Object pojo = pojoList.get(0);
+ return adapterFor(pojo);
+ }
+ }
+ private static ObjectAdapter adapterFor(final Object pojo) {
+ return IsisContext.getPersistenceSession().getAdapterManager().adapterFor(pojo);
+ }
+
+ private static ActionResultResponse toEntityPage(final ActionModel model, final ObjectAdapter actualAdapter, ConcurrencyException exIfAny) {
+ // this will not preserve the URL (because pageParameters are not copied over)
+ // but trying to preserve them seems to cause the 302 redirect to be swallowed somehow
+ final EntityPage entityPage = new EntityPage(actualAdapter, exIfAny);
+ return ActionResultResponse.toPage(entityPage);
+ }
+
+
+ // //////////////////////////////////////
+
+ public static ActionResultResponse determineAndInterpretResult(
+ final ActionModel model,
+ final AjaxRequestTarget target,
+ final ObjectAdapter resultAdapter) {
+ ActionResultResponseType arrt = determineFor(resultAdapter, target);
+ return arrt.interpretResult(model, target, resultAdapter);
+ }
+
+ private static ActionResultResponseType determineFor(
+ final ObjectAdapter resultAdapter,
+ final AjaxRequestTarget target) {
+ if(resultAdapter == null) {
+ return ActionResultResponseType.VOID;
+ }
+ final ObjectSpecification resultSpec = resultAdapter.getSpecification();
+ if (resultSpec.isNotCollection()) {
+ if (resultSpec.getFacet(ValueFacet.class) != null) {
+
+ final Object value = resultAdapter.getObject();
+ if(value instanceof Clob) {
+ return ActionResultResponseType.VALUE_CLOB;
+ }
+ if(value instanceof Blob) {
+ return ActionResultResponseType.VALUE_BLOB;
+ }
+ if(value instanceof java.net.URL) {
+ return target != null? ActionResultResponseType.VALUE_URL_AJAX: ActionResultResponseType.VALUE_URL_NOAJAX;
+ }
+ // else
+ return ActionResultResponseType.VALUE;
+ } else {
+ return ActionResultResponseType.OBJECT;
+ }
+ } else {
+ final List<Object> pojoList = asList(resultAdapter);
+ switch (pojoList.size()) {
+ case 1:
+ return ActionResultResponseType.OBJECT;
+ default:
+ return ActionResultResponseType.COLLECTION;
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static List<Object> asList(final ObjectAdapter resultAdapter) {
+ final Collection<Object> coll = (Collection<Object>) resultAdapter.getObject();
+ return coll instanceof List
+ ? (List<Object>)coll
+ : Lists.<Object>newArrayList(coll);
+ }
+
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/app/registry/ComponentFactoryRegistrar.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/app/registry/ComponentFactoryRegistrar.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/app/registry/ComponentFactoryRegistrar.java
new file mode 100644
index 0000000..5952f0c
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/app/registry/ComponentFactoryRegistrar.java
@@ -0,0 +1,105 @@
+/*
+ * 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.app.registry;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Lists;
+
+import org.apache.isis.viewer.wicket.ui.ComponentFactory;
+import org.apache.isis.viewer.wicket.ui.ComponentType;
+
+/**
+ * Defines an API for registering {@link ComponentFactory}s.
+ *
+ * <p>
+ * As used by {@link ComponentFactoryListDefault}.
+ */
+public interface ComponentFactoryRegistrar {
+
+ public static class ComponentFactoryList implements Iterable<ComponentFactory> {
+ private final List<ComponentFactory> componentFactories = Lists.newArrayList();
+
+ public void add(ComponentFactory componentFactory) {
+ componentFactories.add(componentFactory);
+ }
+
+ public void replace(final ComponentFactory replacementComponentFactory) {
+ removeExisting(matching(replacementComponentFactory.getComponentType()));
+ add(replacementComponentFactory);
+ }
+
+ public void replace(final Class<? extends ComponentFactory> toReplace, final ComponentFactory replacementComponentFactory) {
+ int indexOfOldFactory = removeExisting(matching(toReplace));
+ insert(indexOfOldFactory, replacementComponentFactory);
+ }
+
+ private void insert(final int indexToInsertInto, final ComponentFactory replacementComponentFactory) {
+ if (indexToInsertInto > -1 && indexToInsertInto < componentFactories.size()) {
+ componentFactories.add(indexToInsertInto, replacementComponentFactory);
+ } else {
+ componentFactories.add(replacementComponentFactory);
+ }
+ }
+
+ private int removeExisting(final Predicate<ComponentFactory> predicate) {
+ int indexOfFirst = -1;
+ for (int i = 0; i < componentFactories.size(); i++) {
+ ComponentFactory factory = componentFactories.get(i);
+ if (predicate.apply(factory)) {
+ componentFactories.remove(i);
+ if (indexOfFirst == -1) {
+ indexOfFirst = i;
+ }
+ i--;
+ }
+ }
+
+ return indexOfFirst;
+ }
+
+ private static Predicate<ComponentFactory> matching(final ComponentType componentType) {
+ return new Predicate<ComponentFactory>() {
+ @Override
+ public boolean apply(ComponentFactory input) {
+ return input.getComponentType() == componentType;
+ }
+ };
+ }
+
+ private static Predicate<ComponentFactory> matching(final Class<? extends ComponentFactory> toReplace) {
+ return new Predicate<ComponentFactory>() {
+ @Override
+ public boolean apply(ComponentFactory input) {
+ return toReplace.isAssignableFrom(input.getClass());
+ }
+ };
+ }
+
+ @Override
+ public Iterator<ComponentFactory> iterator() {
+ return componentFactories.iterator();
+ }
+ }
+
+ void addComponentFactories(ComponentFactoryList componentFactoryList);
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/app/registry/ComponentFactoryRegistry.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/app/registry/ComponentFactoryRegistry.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/app/registry/ComponentFactoryRegistry.java
new file mode 100644
index 0000000..f037378
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/app/registry/ComponentFactoryRegistry.java
@@ -0,0 +1,87 @@
+/*
+ * 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.app.registry;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.model.IModel;
+
+import org.apache.isis.viewer.wicket.ui.ComponentFactory;
+import org.apache.isis.viewer.wicket.ui.ComponentType;
+
+/**
+ * API for finding registered {@link ComponentFactory}s.
+ *
+ * <p>
+ * Ultimately all requests to locate {@link ComponentFactory}s are routed
+ * through to an object implementing this interface.
+ */
+public interface ComponentFactoryRegistry {
+
+ List<ComponentFactory> findComponentFactories(ComponentType componentType, IModel<?> model);
+
+ /**
+ * Finds the "best" {@link ComponentFactory} for the viewId.
+ */
+ ComponentFactory findComponentFactory(ComponentType componentType, IModel<?> model);
+
+ /**
+ * As per
+ * {@link #addOrReplaceComponent(MarkupContainer, ComponentType, IModel)},
+ * but with the wicket id derived from the {@link ComponentType}.
+ */
+ Component addOrReplaceComponent(MarkupContainer markupContainer, ComponentType componentType, IModel<?> model);
+
+ /**
+ * {@link #createComponent(ComponentType, String, IModel) Creates} the
+ * relevant {@link Component} for the provided arguments, and adds to the
+ * provided {@link MarkupContainer}; the wicket id is as specified.
+ *
+ * <p>
+ * If none can be found, will fail fast.
+ */
+ Component addOrReplaceComponent(MarkupContainer markupContainer, String id, ComponentType componentType, IModel<?> model);
+
+ /**
+ * As per {@link #createComponent(ComponentType, String, IModel)}, but with
+ * the wicket id derived from the {@link ComponentType}.
+ *
+ * @see #createComponent(ComponentType, String, IModel)
+ */
+ Component createComponent(ComponentType componentType, IModel<?> model);
+
+ /**
+ * Create the {@link Component} matching the specified {@link ComponentType}
+ * and {@link IModel} to the provided {@link MarkupContainer}; the id is
+ * specified explicitly.
+ *
+ * <p>
+ * If none can be found, will fail fast.
+ */
+ Component createComponent(ComponentType componentType, String id, IModel<?> model);
+
+ ComponentFactory findComponentFactoryElseFailFast(ComponentType componentType, IModel<?> model);
+
+ Collection<ComponentFactory> listComponentFactories();
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/app/registry/ComponentFactoryRegistryAccessor.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/app/registry/ComponentFactoryRegistryAccessor.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/app/registry/ComponentFactoryRegistryAccessor.java
new file mode 100644
index 0000000..b433bf4
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/app/registry/ComponentFactoryRegistryAccessor.java
@@ -0,0 +1,31 @@
+/*
+ * 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.app.registry;
+
+import java.io.Serializable;
+
+/**
+ * For obtaining the {@link ComponentFactoryRegistry}.
+ */
+public interface ComponentFactoryRegistryAccessor extends Serializable {
+
+ ComponentFactoryRegistry getComponentFactoryRegistry();
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/AboutPanel.html
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/AboutPanel.html b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/AboutPanel.html
new file mode 100644
index 0000000..c85780d
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/AboutPanel.html
@@ -0,0 +1,26 @@
+<?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.
+-->
+<html xmlns:wicket="http://wicket.apache.org">
+<wicket:panel>
+ <div class="aboutPanel aboutComponentType">
+ <div wicket:id="manifestAttributes"></div>
+ </div>
+</wicket:panel>
+</html>
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/AboutPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/AboutPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/AboutPanel.java
new file mode 100644
index 0000000..68f16fa
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/AboutPanel.java
@@ -0,0 +1,69 @@
+/*
+ * 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.components.about;
+
+import java.io.InputStream;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import org.apache.isis.viewer.wicket.model.models.AboutModel;
+import org.apache.isis.viewer.wicket.ui.pages.home.HomePage;
+import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
+
+/**
+ * {@link PanelAbstract Panel} displaying welcome message (as used on
+ * {@link HomePage}).
+ */
+public class AboutPanel extends PanelAbstract<AboutModel> {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String ID_MANIFEST_ATTRIBUTES = "manifestAttributes";
+
+ @Inject
+ @Named("aboutMessage")
+ private String aboutMessage;
+
+ /**
+ * We take care to read this only once.
+ *
+ * <p>
+ * Is <code>transient</code> because
+ * </p>
+ */
+ @Inject
+ @Named("metaInfManifest")
+ private transient InputStream metaInfManifestIs;
+
+ private JarManifestModel jarManifestModel;
+
+ public AboutPanel(final String id) {
+ super(id);
+
+ if(jarManifestModel == null) {
+ jarManifestModel = new JarManifestModel(aboutMessage, metaInfManifestIs);
+ }
+
+ add(new JarManifestPanel(ID_MANIFEST_ATTRIBUTES, jarManifestModel));
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/AboutPanelFactory.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/AboutPanelFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/AboutPanelFactory.java
new file mode 100644
index 0000000..3439855
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/AboutPanelFactory.java
@@ -0,0 +1,50 @@
+/*
+ * 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.components.about;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.model.IModel;
+import org.apache.isis.viewer.wicket.ui.ComponentFactory;
+import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
+import org.apache.isis.viewer.wicket.ui.ComponentType;
+
+/**
+ * {@link ComponentFactory} for {@link AboutPanel}.
+ */
+public class AboutPanelFactory extends ComponentFactoryAbstract {
+
+ private static final long serialVersionUID = 1L;
+
+ public AboutPanelFactory() {
+ super(ComponentType.ABOUT, AboutPanel.class);
+ }
+
+ @Override
+ public ApplicationAdvice appliesTo(final IModel<?> model) {
+ return ApplicationAdvice.APPLIES;
+ }
+
+ @Override
+ public Component createComponent(final String id, final IModel<?> model) {
+ return new AboutPanel(id);
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestAttributes.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestAttributes.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestAttributes.java
new file mode 100644
index 0000000..fac290c
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestAttributes.java
@@ -0,0 +1,68 @@
+/*
+ * 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.components.about;
+
+import java.io.Serializable;
+import java.net.URL;
+import java.util.Map.Entry;
+
+public class JarManifestAttributes implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ public static JarManifestAttributes jarName(String jarName) {
+ return new JarManifestAttributes(JarManifestAttributes.Type.JAR_NAME, jarName);
+ }
+
+ public static JarManifestAttributes jarUrl(URL jarUrl) {
+ return new JarManifestAttributes(JarManifestAttributes.Type.JAR_URL, jarUrl != null? jarUrl.toExternalForm(): "");
+ }
+
+ public static JarManifestAttributes attribute(Entry<Object,Object> entry) {
+ StringBuilder buf = new StringBuilder();
+ buf .append(" ")
+ .append(entry.getKey())
+ .append(": ")
+ .append(entry.getValue())
+ .append("\n")
+ ;
+ return new JarManifestAttributes(JarManifestAttributes.Type.MANIFEST_ATTRIBUTE, buf.toString());
+ }
+
+ enum Type {
+ JAR_NAME,
+ JAR_URL,
+ MANIFEST_ATTRIBUTE
+ }
+
+ private final Type type;
+ private final String line;
+
+ public JarManifestAttributes(Type type, String line) {
+ this.type = type;
+ this.line = line;
+ }
+ public JarManifestAttributes.Type getType() {
+ return type;
+ }
+ public String getLine() {
+ return line;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestListView.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestListView.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestListView.java
new file mode 100644
index 0000000..1565ac9
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestListView.java
@@ -0,0 +1,45 @@
+/*
+ * 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.components.about;
+
+import java.util.List;
+
+import org.apache.wicket.behavior.AttributeAppender;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+
+public final class JarManifestListView extends ListView<JarManifestAttributes> {
+
+ private static final long serialVersionUID = 1L;
+ private final String idLine;
+
+ public JarManifestListView(String id, String idLine, List<? extends JarManifestAttributes> list) {
+ super(id, list);
+ this.idLine = idLine;
+ }
+
+ @Override
+ protected void populateItem(ListItem<JarManifestAttributes> item) {
+ final JarManifestAttributes detail = item.getModelObject();
+ Label label = new Label(idLine, detail.getLine());
+ item.add(new AttributeAppender("class", detail.getType().name().toLowerCase()));
+ item.add(label);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestModel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestModel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestModel.java
new file mode 100644
index 0000000..d78a290
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestModel.java
@@ -0,0 +1,233 @@
+/*
+ * 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.components.about;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+
+import org.apache.isis.core.commons.lang.CloseableExtensions;
+import org.apache.isis.viewer.wicket.model.models.ModelAbstract;
+
+public class JarManifestModel extends ModelAbstract<JarManifestModel> {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final List<String> VERSION_KEY_CANDIDATES = Arrays.asList("Implementation-Version", "Build-Time");
+
+ private String aboutMessage;
+
+ private final List<JarManifestAttributes> manifests = Lists.newArrayList();
+
+ /**
+ * @param aboutMessage
+ * @param metaInfManifestIs provide using <tt>getServletContext().getResourceAsStream("/META-INF/MANIFEST.MF")</tt>
+ */
+ public JarManifestModel(String aboutMessage, InputStream metaInfManifestIs) {
+
+ this.aboutMessage = aboutMessage;
+
+ Manifest manifest;
+ try {
+ manifest = new Manifest(metaInfManifestIs);
+ manifests.add(JarManifestAttributes.jarName("Web archive (war file)"));
+ manifests.add(JarManifestAttributes.jarUrl(null));
+ addAttributes(manifest, manifests);
+
+ // append the version if able to guess
+ String versionIfAny = guessVersion(manifest);
+ this.aboutMessage = this.aboutMessage + (versionIfAny != null? "\n\n" + versionIfAny: "");
+
+ } catch (Exception ex) {
+ // ignore
+ } finally {
+ CloseableExtensions.closeSafely(metaInfManifestIs);
+ }
+
+ Enumeration<?> resEnum;
+ try {
+ resEnum = Thread.currentThread().getContextClassLoader().getResources(JarFile.MANIFEST_NAME);
+ } catch (IOException e) {
+ return;
+ }
+ final List<JarManifest> jarManifests = Lists.newArrayList();
+ while (resEnum.hasMoreElements()) {
+ URL url = (URL)resEnum.nextElement();
+ JarManifest jarManifest = new JarManifest(url);
+ jarManifests.add(jarManifest);
+
+ InputStream is = null;
+ try {
+ is = url.openStream();
+ if (is != null) {
+ manifest = new Manifest(is);
+ jarManifest.addAttributesFrom(manifest);
+ }
+ } catch(Exception e3) {
+ // ignore
+ } finally {
+ CloseableExtensions.closeSafely(is);
+ }
+ }
+
+ Collections.sort(jarManifests);
+
+ for (JarManifest jarManifest : jarManifests) {
+ jarManifest.addAttributesTo(manifests);
+ }
+ }
+
+ private static class JarManifest implements Comparable<JarManifest> {
+ private final List<JarManifestAttributes> attributes = Lists.newArrayList();
+
+ private final URL url;
+
+ private JarName jarName;
+
+ public JarManifest(URL url) {
+ this.url = url;
+ jarName = asJarName(url);
+ }
+
+ void addAttributesFrom(Manifest manifest) {
+ addAttributes(manifest, attributes);
+ }
+
+ void addAttributesTo(List<JarManifestAttributes> manifests) {
+ manifests.add(JarManifestAttributes.jarName(jarName.name));
+ manifests.add(JarManifestAttributes.jarUrl(url));
+ manifests.addAll(attributes);
+ }
+
+ @Override
+ public int compareTo(JarManifest o) {
+ return jarName.compareTo(o.jarName);
+ }
+ }
+
+ static class JarName implements Comparable<JarName>{
+ enum Type {
+ CLASSES, JAR, OTHER
+ }
+ Type type;
+ String name;
+ JarName(Type type, String name) {
+ this.type = type;
+ this.name = name;
+ }
+ @Override
+ public int compareTo(JarName o) {
+ int x = type.compareTo(o.type);
+ if(x != 0) return x;
+ return name.compareTo(o.name);
+ }
+ }
+
+ private static JarName asJarName(URL url) {
+ final String path = url.getPath();
+ // strip off the meta-inf
+ String strippedPath = stripSuffix(path, "/META-INF/MANIFEST.MF");
+ strippedPath = stripSuffix(strippedPath, "!");
+
+ // split the path into parts, and reverse
+ List<String> parts = Lists.newArrayList(Splitter.on(CharMatcher.anyOf("/\\")).split(strippedPath));
+ Collections.reverse(parts);
+
+ // searching from the end, return the jar name if possible
+ for (String part : parts) {
+ if(part.endsWith(".jar")) {
+ return new JarName(JarName.Type.JAR, part);
+ }
+ }
+
+ // see if running in an IDE, under target*/classes; return the part prior to that.
+ if(parts.size()>=3) {
+ if(parts.get(0).equals("classes") && parts.get(1).startsWith("target")) {
+ return new JarName(JarName.Type.CLASSES, parts.get(2));
+ }
+ }
+
+ // otherwise, return the stripped path
+ return new JarName(JarName.Type.OTHER, strippedPath);
+ }
+
+ public static String stripSuffix(String path, String suffix) {
+ int indexOf = path.indexOf(suffix);
+ if(indexOf != -1) {
+ path = path.substring(0, indexOf);
+ }
+ return path;
+ }
+
+ static void addAttributes(Manifest manifest, List<JarManifestAttributes> attributes) {
+ final Attributes mainAttribs = manifest.getMainAttributes();
+ Set<Entry<Object, Object>> entrySet = mainAttribs.entrySet();
+ for (Entry<Object, Object> entry : entrySet) {
+ JarManifestAttributes attribute = JarManifestAttributes.attribute(entry);
+ attributes.add(attribute);
+ }
+ }
+
+
+ private static String guessVersion(Manifest manifest) {
+ final Attributes mainAttribs = manifest.getMainAttributes();
+ Set<Entry<Object, Object>> entrySet = mainAttribs.entrySet();
+ for (String candidate : VERSION_KEY_CANDIDATES) {
+ for (Entry<Object, Object> entry : entrySet) {
+ if(candidate.equals(entry.getKey().toString())) {
+ return entry.getValue().toString();
+ }
+ }
+ }
+ return null;
+ }
+
+
+ @Override
+ protected JarManifestModel load() {
+ return this;
+ }
+
+ @Override
+ public void setObject(JarManifestModel ex) {
+ // no-op
+ }
+
+ public String getAboutMessage() {
+ return aboutMessage;
+ }
+
+ public List<JarManifestAttributes> getDetail() {
+ return manifests;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestPanel.css
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestPanel.css b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestPanel.css
new file mode 100644
index 0000000..2f05abd
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestPanel.css
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+ .jarManifestPanel .aboutInfo {
+ margin-left: 50px;
+ margin-right: 50px;
+ padding-top: 50px;
+}
+
+
+.jarManifestPanel .aboutMessage {
+ background:#FFFFFF;
+ border-radius:4px;
+ -moz-border-radius:4px;
+ -webkit-border-radius:4px;
+ padding: 15px;
+ display: block;
+ text-align:center;
+ font-size:1.2em;
+}
+
+ .jarManifestPanel .manifestAttributes {
+ margin-top: 30px;
+}
+
+.jarManifestPanel .heading {
+ display:block;
+ font-style:normal !important;
+
+ padding:1px 6px 1px 6px;
+}
+
+.jarManifestPanel .heading span {
+ display:block;
+ font-style:normal !important;
+ padding:3px 3px 3px 3px;
+ font-size: 0.8em;
+ font-weight:bold;
+}
+
+.jarManifestPanel .heading:hover {
+ background-color:#FFFFFF;
+ cursor: pointer;
+}
+
+.jarManifestPanel h3 {
+ font-size: larger;
+}
+
+.jarManifestPanel .manifestAttributesList .caused_by_label {
+ margin-top: 30px;
+ font-style:normal !important;
+ font-size: 0.8em;
+ font-weight:bold;
+ color: #46423C;
+}
+
+.jarManifestPanel .manifestAttributesList .jar_name {
+ margin-top: 15px;
+ font-size: 1.2em;
+ font-weight:bold;
+ color: #46423C;
+}
+
+.jarManifestPanel .manifestAttributesList .jar_url {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ font-style: italic;
+ font-size: 1.0em;
+ color: #00477F;
+}
+
+.jarManifestPanel .manifestAttributesList .manifest_attribute{
+ margin-left: 30px;
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestPanel.html
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestPanel.html b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestPanel.html
new file mode 100644
index 0000000..340922a
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestPanel.html
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<!--
+ 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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"
+ xml:lang="en"
+ lang="en">
+ <body>
+ <wicket:panel>
+ <div class="jarManifestPanel">
+ <div class="aboutInfo clear">
+ <h2 wicket:id="aboutMessage" class="aboutMessage">[about message text]</h2>
+ <div class="manifestAttributes" wicket:id="manifestAttributes">
+ <h4 class="heading well">Jar manifest attributes</h4>
+ <div class="content">
+ <div class="manifestAttributesList">
+ <ul>
+ <li wicket:id="manifestAttribute">
+ <span wicket:id="manifestAttributeLine">[manifest attribute line]</span>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </wicket:panel>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestPanel.java
new file mode 100644
index 0000000..8a76487
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/JarManifestPanel.java
@@ -0,0 +1,68 @@
+/*
+ * 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.components.about;
+
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.JavaScriptReferenceHeaderItem;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.request.resource.JavaScriptResourceReference;
+import org.apache.isis.viewer.wicket.ui.panels.PanelUtil;
+
+public class JarManifestPanel extends Panel {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String ID_ABOUT_MESSAGE = "aboutMessage";
+
+ private static final String ID_MANIFEST_ATTRIBUTES = "manifestAttributes";
+
+ private static final String ID_MANIFEST_ATTRIBUTE = "manifestAttribute";
+ private static final String ID_LINE = "manifestAttributeLine";
+
+ private static final JavaScriptResourceReference DIV_TOGGLE_JS = new JavaScriptResourceReference(JarManifestPanel.class, "div-toggle.js");
+
+ public JarManifestPanel(String id, JarManifestModel manifestModel) {
+ super(id, manifestModel);
+
+ final String aboutMessage = manifestModel.getAboutMessage();
+ final Label label = new Label(ID_ABOUT_MESSAGE, aboutMessage);
+ // safe to not escape, about message is read from file (part of deployed WAR)
+ label.setEscapeModelStrings(false);
+ add(label);
+
+ MarkupContainer container = new WebMarkupContainer(ID_MANIFEST_ATTRIBUTES) {
+ private static final long serialVersionUID = 1L;
+ @Override
+ public void renderHead(IHeaderResponse response) {
+ response.render(JavaScriptReferenceHeaderItem.forReference(DIV_TOGGLE_JS));
+ }
+ };
+ container.add(new JarManifestListView(ID_MANIFEST_ATTRIBUTE, JarManifestPanel.ID_LINE, manifestModel.getDetail()));
+ add(container);
+ }
+
+ public void renderHead(final IHeaderResponse response) {
+ PanelUtil.renderHead(response, this.getClass());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/div-toggle.js
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/div-toggle.js b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/div-toggle.js
new file mode 100644
index 0000000..d51175a
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/about/div-toggle.js
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+jQuery(document).ready(function() {
+ jQuery(".jarManifestPanel .content").hide();
+ jQuery(".jarManifestPanel .heading").click(function()
+ {
+ jQuery(this).next(".jarManifestPanel .content").slideToggle(500);
+ });
+});
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionlink/ActionLinkPanel.html
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionlink/ActionLinkPanel.html b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionlink/ActionLinkPanel.html
new file mode 100644
index 0000000..e239527
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionlink/ActionLinkPanel.html
@@ -0,0 +1,31 @@
+<?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.
+-->
+<html xmlns:wicket="http://wicket.apache.org">
+ <body>
+ <wicket:panel>
+ <span wicket:id="actionLinkWrapper" class="actionLinkPanel actionLinkComponentType">
+ <a href="#" wicket:id="actionLink">
+ <span wicket:id="actionTitle" class="actionTitle">[action title]</span>
+ </a>
+ </span>
+ </wicket:panel>
+ </body>
+</html>
+
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionlink/ActionLinkPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionlink/ActionLinkPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionlink/ActionLinkPanel.java
new file mode 100644
index 0000000..0b81418
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionlink/ActionLinkPanel.java
@@ -0,0 +1,101 @@
+/*
+ * 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.components.actionlink;
+
+import org.apache.wicket.Page;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.AbstractLink;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+import org.apache.isis.viewer.wicket.model.models.ActionModel;
+import org.apache.isis.viewer.wicket.model.models.EntityModel;
+import org.apache.isis.viewer.wicket.model.models.PageType;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistryAccessor;
+import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
+import org.apache.isis.viewer.wicket.ui.util.Links;
+
+/**
+ * {@link PanelAbstract Panel} representing the icon and title of an entity,
+ * as per the provided {@link EntityModel}.
+ */
+public class ActionLinkPanel extends PanelAbstract<ActionModel> {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String ID_ACTION_LINK_WRAPPER = "actionLinkWrapper";
+ private static final String ID_ACTION_LINK = "actionLink";
+ private static final String ID_ACTION_TITLE = "actionTitle";
+
+ private Label label;
+
+ public ActionLinkPanel(final String id, final ActionModel actionModel) {
+ super(id, actionModel);
+ }
+
+ @Override
+ protected void onBeforeRender() {
+ buildGui();
+ super.onBeforeRender();
+ }
+
+ private void buildGui() {
+ addOrReplaceLinkWrapper();
+ }
+
+ private void addOrReplaceLinkWrapper() {
+ final WebMarkupContainer entityLinkWrapper = addOrReplaceLinkWrapper(getModel());
+ addOrReplace(entityLinkWrapper);
+ }
+
+ private WebMarkupContainer addOrReplaceLinkWrapper(final ActionModel actionModel) {
+
+ final PageParameters pageParameters = actionModel.getPageParameters();
+ final Class<? extends Page> pageClass = getPageClassRegistry().getPageClass(PageType.ACTION_PROMPT);
+ final AbstractLink link = newLink(ID_ACTION_LINK, pageClass, pageParameters);
+
+ label = new Label(ID_ACTION_TITLE, determineTitle());
+ link.add(label);
+
+ final WebMarkupContainer actionLinkWrapper = new WebMarkupContainer(ID_ACTION_LINK_WRAPPER);
+ actionLinkWrapper.addOrReplace(link);
+ return actionLinkWrapper;
+ }
+
+ private String determineTitle() {
+ return getModel().getActionMemento().getAction().getId();
+ }
+
+ private AbstractLink newLink(final String linkId, final Class<? extends Page> pageClass, final PageParameters pageParameters) {
+ return Links.newBookmarkablePageLink(linkId, pageParameters, pageClass);
+ }
+
+
+ // ///////////////////////////////////////////////////////////////////
+ // Convenience
+ // ///////////////////////////////////////////////////////////////////
+
+ protected PageClassRegistry getPageClassRegistry() {
+ final PageClassRegistryAccessor pcra = (PageClassRegistryAccessor) getApplication();
+ return pcra.getPageClassRegistry();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionlink/ActionLinkPanelFactory.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionlink/ActionLinkPanelFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionlink/ActionLinkPanelFactory.java
new file mode 100644
index 0000000..f36ac36
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionlink/ActionLinkPanelFactory.java
@@ -0,0 +1,59 @@
+/*
+ * 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.components.actionlink;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.model.IModel;
+
+import org.apache.isis.applib.annotation.ActionSemantics;
+import org.apache.isis.viewer.wicket.model.models.ActionModel;
+import org.apache.isis.viewer.wicket.ui.ComponentFactory;
+import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
+import org.apache.isis.viewer.wicket.ui.ComponentType;
+
+/**
+ * {@link ComponentFactory} for {@link ActionLinkPanel}.
+ */
+public class ActionLinkPanelFactory extends ComponentFactoryAbstract {
+
+ private static final long serialVersionUID = 1L;
+
+ public ActionLinkPanelFactory() {
+ super(ComponentType.ACTION_LINK, ActionLinkPanel.class);
+ }
+
+ @Override
+ protected ApplicationAdvice appliesTo(IModel<?> model) {
+ if(!(model instanceof ActionModel)) {
+ return ApplicationAdvice.DOES_NOT_APPLY;
+ }
+ final ActionModel actionModel = (ActionModel) model;
+ final ActionSemantics.Of semantics = actionModel.getActionMemento().getAction().getSemantics();
+ return ApplicationAdvice.appliesIf(semantics.isSafeInNature());
+ }
+
+ @Override
+ public Component createComponent(final String id, final IModel<?> model) {
+ final ActionModel actionModel = (ActionModel) model;
+ return new ActionLinkPanel(id, actionModel);
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/99094b7e/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/CssClassFaBehavior.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/CssClassFaBehavior.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/CssClassFaBehavior.java
new file mode 100644
index 0000000..58294c9
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/CssClassFaBehavior.java
@@ -0,0 +1,54 @@
+/*
+ * 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.components.actionmenu;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.isis.core.metamodel.facets.members.cssclassfa.CssClassFaPosition;
+
+/**
+ * A behavior that prepends or appends the markup needed to show a Font Awesome icon
+ * for a LinkAndLabel
+ */
+public class CssClassFaBehavior extends Behavior {
+
+ private final String cssClassFa;
+ private final CssClassFaPosition position;
+
+ public CssClassFaBehavior(final String cssClassFa, final CssClassFaPosition position) {
+ this.cssClassFa = cssClassFa;
+ this.position = position;
+ }
+
+ @Override
+ public void beforeRender(final Component component) {
+ super.beforeRender(component);
+ if (position == null || CssClassFaPosition.LEFT == position) {
+ component.getResponse().write("<span class=\""+cssClassFa+" fontAwesomeIcon\"></span>");
+ }
+ }
+
+ @Override
+ public void afterRender(final Component component) {
+ if (CssClassFaPosition.RIGHT == position) {
+ component.getResponse().write("<span class=\""+cssClassFa+" fontAwesomeIcon\"></span>");
+ }
+ super.afterRender(component);
+ }
+}