Index: addon-cms/src/main/java/org/onehippo/forge/selection/frontend/plugin/DynamicDropdownPlugin.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- addon-cms/src/main/java/org/onehippo/forge/selection/frontend/plugin/DynamicDropdownPlugin.java (revision 852)
+++ addon-cms/src/main/java/org/onehippo/forge/selection/frontend/plugin/DynamicDropdownPlugin.java (revision )
@@ -15,8 +15,11 @@
*/
package org.onehippo.forge.selection.frontend.plugin;
+import org.apache.commons.lang.StringUtils;
import org.apache.wicket.AttributeModifier;
+import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.Page;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
import org.apache.wicket.extensions.markup.html.form.select.IOptionRenderer;
@@ -48,30 +51,27 @@
import org.slf4j.LoggerFactory;
import javax.jcr.RepositoryException;
+
import java.io.Serializable;
import java.util.*;
/**
- * A dynamic dropdown plugin, which is backed by a ValueListProvider service
- * that provides a ValueList object.
+ * A dynamic dropdown plugin, which is backed by a ValueListProvider service that provides a ValueList object.
*
- * The plugin configuration can be provided with a valuelist.provider
- * property, defaulting to "service.valuelist.default", which is the name of the
- * DocumentValueListProvider.
+ * The plugin configuration can be provided with a valuelist.provider
property, defaulting to
+ * "service.valuelist.default", which is the name of the DocumentValueListProvider.
*
- * The default DocumentValueListProvider reads a document of the type
- * 'selection:valuelist', which contains key label pairs used to display values
- * and labels in the dropdown.
+ * The default DocumentValueListProvider reads a document of the type 'selection:valuelist', which contains key label
+ * pairs used to display values and labels in the dropdown.
*
- * The plugin configuration must then be provided with a source
- * property, which can either be a valid UUID of a handle or the path to the
- * document based on the JCR root.
+ * The plugin configuration must then be provided with a source
property, which can either be a valid UUID
+ * of a handle or the path to the document based on the JCR root.
*
- * List items that have a group name set, will be grouped together using OPTGROUP elements. Groups can be mixed
- * with regular option elements. Groups and options without a group are shown in the order they are encountered
- * in the {@link org.onehippo.forge.selection.frontend.model.ValueList} used.
+ * List items that have a group name set, will be grouped together using OPTGROUP elements. Groups can be mixed with
+ * regular option elements. Groups and options without a group are shown in the order they are encountered in the
+ * {@link org.onehippo.forge.selection.frontend.model.ValueList} used.
*/
-public class DynamicDropdownPlugin extends RenderPlugin {
+public class DynamicDropdownPlugin extends RenderPlugin implements AjaxUpdatesAware {
private static final String SERVICE_VALUELIST_DEFAULT = "service.valuelist.default";
@@ -81,7 +81,7 @@
private final SortHelper sortHelper = new SortHelper();
@SuppressWarnings("unchecked")
- public DynamicDropdownPlugin(IPluginContext context, IPluginConfig config) {
+ public DynamicDropdownPlugin(final IPluginContext context, final IPluginConfig config) {
super(context, config);
// check the cnd for multiple, this is not supported (NB: check doesn't work for relaxed cnd)
@@ -89,8 +89,8 @@
final boolean multiple = getValueModel().getJcrPropertymodel().getProperty().getDefinition().isMultiple();
if (multiple) {
throw new IllegalStateException(this.getClass().getName() + " does not support fields that are multiple, " +
- "please use " + DynamicMultiSelectPlugin.class.getName() + " for that." +
- " Field name is " + getValueModel().getJcrPropertymodel().getProperty().getDefinition().getName() + ".");
+ "please use " + DynamicMultiSelectPlugin.class.getName() + " for that." +
+ " Field name is " + getValueModel().getJcrPropertymodel().getProperty().getDefinition().getName() + ".");
}
} catch (RepositoryException e) {
throw new InstantiationError("Error instantiating " + this.getClass().getName() + ": " + e.getMessage());
@@ -98,117 +98,134 @@
add(CSSPackageResource.getHeaderContribution(DynamicDropdownPlugin.class, "DynamicDropdownPlugin.css"));
- final String mode = config.getString(ITemplateEngine.MODE);
-
- // configured provider, or the default
- String providerName = config.getString(Config.VALUELIST_PROVIDER, SERVICE_VALUELIST_DEFAULT);
- IValueListProvider selectedProvider = context.getService(providerName, IValueListProvider.class);
-
- if (selectedProvider == null && !SERVICE_VALUELIST_DEFAULT.equals(providerName)) {
- selectedProvider = context.getService(SERVICE_VALUELIST_DEFAULT, IValueListProvider.class);
+ final ValueList valueList = getValueList(config.getString(Config.SOURCE));
+ if(valueList == null) {
+ return;
}
- if (selectedProvider == null) {
- log.warn("DynamicDropdownPlugin: value list provider can not be found by name '{}'",
- config.getString(Config.VALUELIST_PROVIDER));
+ final String mode = config.getString(ITemplateEngine.MODE);
+ List selectItems = getInternalDropdownModel(valueList);
+ if ("edit".equals(mode)) {
+ add(getSelect(config, valueList, selectItems));
- DropDownChoice dummyChoice = new DropDownChoice("selectDropdown");
+ Label valueLabel = new Label("selectLabel");
+ valueLabel.setVisibilityAllowed(false);
+ add(valueLabel);
+ } else {
+ DropDownChoice> dummyChoice = new DropDownChoice("selectDropdown");
dummyChoice.setVisibilityAllowed(false);
add(dummyChoice);
- Label valueLabel = new Label("selectLabel", new Model("-"));
- add(valueLabel);
- return;
+
+ Label label = null;
+ if ("compare".equals(mode)) {
+ if (config.containsKey("model.compareTo")) {
+ IModelReference baseRef = context.getService(config.getString("model.compareTo"),
+ IModelReference.class);
+ if (baseRef != null) {
+ IModel baseModel = baseRef.getModel();
+ if (baseModel == null) {
+ log.info("base model service provides null model");
+ baseModel = new Model(null);
- }
+ }
+ IModel baseLabel = new ValueLabelModel(valueList, baseModel);
+ IModel curLabel = new ValueLabelModel(valueList, getValueModel());
+ label = (Label) new Label("selectLabel", new TextDiffModel(baseLabel, curLabel))
+ .setEscapeModelStrings(false);
+ } else {
+ log.warn("opened in compare mode, but no base model service is available");
+ }
+ } else {
+ log.warn("opened in compare mode, but no base model was configured");
+ }
+ }
+ if (label == null) {
+ label = new Label("selectLabel", new ValueLabelModel(valueList, getModel()));
+ }
+ add(label);
+ }
+ }
- final Locale locale = SelectionUtils.getLocale(SelectionUtils.getNode(getModel()));
- final ValueList valueList = selectedProvider.getValueList(config.getString(Config.SOURCE), locale);
-
- sortHelper.sort(valueList, config);
-
- List selectItems = getInternalDropdownModel(valueList);
- if ("edit".equals(mode)) {
+ private Select getSelect(final IPluginConfig config, final ValueList valueList, final List selectItems) {
- final IOptionRenderer optionRenderer = new IOptionRenderer() {
- private static final long serialVersionUID = 1L;
+ final IOptionRenderer optionRenderer = new IOptionRenderer() {
+ private static final long serialVersionUID = 1L;
- public String getDisplayValue(String option) {
- return valueList.getListItemByKey(option).getLabel();
- }
+ public String getDisplayValue(String option) {
+ return valueList.getListItemByKey(option).getLabel();
+ }
- public IModel getModel(String option) {
- return new Model(option);
- }
- };
- Select select = new Select("selectDropdown", getValueModel());
- RepeatingView optionsListView = new RepeatingView("selectDropdownItem");
+ public IModel getModel(String option) {
+ return new Model(option);
+ }
+ };
+ Select select = new Select("selectDropdown", getValueModel());
+ RepeatingView optionsListView = new RepeatingView("selectDropdownItem");
- int i = 0;
- for (InternalSelectItem selectItem : selectItems) {
- if (selectItem instanceof InternalSelectOptionGroup) {
- InternalSelectOptionGroup optionGroup = (InternalSelectOptionGroup) selectItem;
- Fragment optionGroupFragment = new OptionGroupFragment("dropdownListViewItem-" + i++,
- "selectOptionGroup", optionGroup, optionRenderer);
- optionGroupFragment.setRenderBodyOnly(true);
- optionsListView.add(optionGroupFragment);
- } else {
- InternalSelectOption option = (InternalSelectOption) selectItem;
- OptionFragment optionFragment = new OptionFragment("dropdownListViewItem-" + i++, "selectOption",
- option);
- optionFragment.setRenderBodyOnly(true);
- optionsListView.add(optionFragment);
- }
- }
- select.add(optionsListView);
+ int i = 0;
+ for (InternalSelectItem selectItem : selectItems) {
+ if (selectItem instanceof InternalSelectOptionGroup) {
+ InternalSelectOptionGroup optionGroup = (InternalSelectOptionGroup) selectItem;
+ Fragment optionGroupFragment = new OptionGroupFragment("dropdownListViewItem-" + i++,
+ "selectOptionGroup", optionGroup, optionRenderer);
+ optionGroupFragment.setRenderBodyOnly(true);
+ optionsListView.add(optionGroupFragment);
+ } else {
+ InternalSelectOption option = (InternalSelectOption) selectItem;
+ OptionFragment optionFragment = new OptionFragment("dropdownListViewItem-" + i++, "selectOption",
+ option);
+ optionFragment.setRenderBodyOnly(true);
+ optionsListView.add(optionFragment);
+ }
+ }
+ select.add(optionsListView);
- select.add(new OnChangeAjaxBehavior() {
- private static final long serialVersionUID = 1L;
+ select.add(new OnChangeAjaxBehavior() {
+ private static final long serialVersionUID = 1L;
- @Override
- protected void onUpdate(AjaxRequestTarget target) {
+ @Override
+ protected void onUpdate(AjaxRequestTarget target) {
+ final String broadcastEventId = config.getString(Config.BROADCAST_EVENT_ID);
+ if (StringUtils.isNotEmpty(broadcastEventId)) {
+ log.debug("Broadcasting event {}", broadcastEventId);
+ System.out.println("Broadcasting event: " + broadcastEventId);
+ broadcastEvent(target, getPage(), broadcastEventId, getModelObject());
}
+ }
- });
+ });
- add(select);
+ return select;
+ }
- Label valueLabel = new Label("selectLabel");
- valueLabel.setVisibilityAllowed(false);
- add(valueLabel);
- } else {
- DropDownChoice> dummyChoice = new DropDownChoice("selectDropdown");
+ private ValueList getValueList(String path) {
+ // configured provider, or the default
+ String providerName = getPluginConfig().getString(Config.VALUELIST_PROVIDER, SERVICE_VALUELIST_DEFAULT);
+ IValueListProvider selectedProvider = getPluginContext().getService(providerName, IValueListProvider.class);
+
+ if (selectedProvider == null && !SERVICE_VALUELIST_DEFAULT.equals(providerName)) {
+ selectedProvider = getPluginContext().getService(SERVICE_VALUELIST_DEFAULT, IValueListProvider.class);
+ }
+
+ if (selectedProvider == null) {
+ log.warn("DynamicDropdownPlugin: value list provider can not be found by name '{}'",
+ getPluginConfig().getString(Config.VALUELIST_PROVIDER));
+
+ DropDownChoice dummyChoice = new DropDownChoice("selectDropdown");
dummyChoice.setVisibilityAllowed(false);
add(dummyChoice);
+ Label valueLabel = new Label("selectLabel", new Model("-"));
+ add(valueLabel);
+ return null;
+ }
- Label label = null;
- if ("compare".equals(mode)) {
- if (config.containsKey("model.compareTo")) {
- IModelReference baseRef = context.getService(config.getString("model.compareTo"),
- IModelReference.class);
- if (baseRef != null) {
- IModel baseModel = baseRef.getModel();
- if (baseModel == null) {
- log.info("base model service provides null model");
- baseModel = new Model(null);
+ final Locale locale = SelectionUtils.getLocale(SelectionUtils.getNode(getModel()));
+ final ValueList valueList = selectedProvider.getValueList(path, locale);
+ sortHelper.sort(valueList, getPluginConfig());
+
+ return valueList;
- }
+ }
- IModel baseLabel = new ValueLabelModel(valueList, baseModel);
- IModel curLabel = new ValueLabelModel(valueList, getValueModel());
- label = (Label) new Label("selectLabel", new TextDiffModel(baseLabel, curLabel))
- .setEscapeModelStrings(false);
- } else {
- log.warn("opened in compare mode, but no base model service is available");
- }
- } else {
- log.warn("opened in compare mode, but no base model was configured");
- }
- }
- if (label == null) {
- label = new Label("selectLabel", new ValueLabelModel(valueList, getModel()));
- }
- add(label);
- }
- }
private List getInternalDropdownModel(ValueList valueList) {
List selectItems = new ArrayList(valueList.size());
selectItems.add(new InternalSelectOption("",
- new StringResourceModel("choose.one", DynamicDropdownPlugin.this, null).getString()));
+ new StringResourceModel("choose.one", DynamicDropdownPlugin.this, null).getString()));
Map groupsSoFar = new HashMap();
for (ListItem listItem : valueList) {
if (isGroupItem(listItem)) {
@@ -234,6 +251,36 @@
return (JcrPropertyValueModel) getModel();
}
+ @Override
+ public void onAjaxUpdate(AjaxRequestTarget target, final String eventId, final Object message) {
+ final String receiveEventId = getPluginConfig().getString(Config.RECEIVE_EVENT_ID);
+ if (StringUtils.equals(receiveEventId, eventId)) {
+ log.info("Received message: " + message);
+ System.out.println("Received eventId: " + eventId + " message: " + message);
+ // TODO: change source valuelist
+
+ String valueListName = "/content/documents/valuelists/" + message;
+ final ValueList valueList = getValueList(valueListName);
+
+ List selectItems = getInternalDropdownModel(valueList);
+ replace(getSelect(getPluginConfig(), valueList, selectItems));
+ DynamicDropdownPlugin.this.redraw();
+ }
+ }
+
+ protected void broadcastEvent(final AjaxRequestTarget target, final Page page, final String eventId, final Object message) {
+ page.visitChildren(new Component.IVisitor() {
+ @Override
+ public Object component(final Component component) {
+ if(component instanceof AjaxUpdatesAware) {
+ ((AjaxUpdatesAware) component).onAjaxUpdate(target, eventId, message);
+ }
+ return null;
+ }
+ });
+ }
+
+
private abstract static class InternalSelectItem {
private String label;
@@ -285,15 +332,15 @@
private static final long serialVersionUID = 1L;
public OptionGroupFragment(String id, String markupId, InternalSelectOptionGroup optionGroup,
- IOptionRenderer optionRenderer) {
+ IOptionRenderer optionRenderer) {
super(id, markupId, DynamicDropdownPlugin.this);
// a container is bound to the optgroup element, so we can set the label on the optgroup element
MarkupContainer container = new WebMarkupContainer("optionGroup");
container.add(new AttributeModifier("label", new StringResourceModel(optionGroup.getLabel(), this, null,
- optionGroup.getLabel())));
+ optionGroup.getLabel())));
// the SelectOptions widget is a repeating view. This widget will thus replace the tag to which it is bound
SelectOptions optionGroupCmpt = new SelectOptions("optionGroupItems", optionGroup
- .getOptions(), optionRenderer);
+ .getOptions(), optionRenderer);
container.add(optionGroupCmpt);
add(container);
}
@@ -302,8 +349,8 @@
/**
* Fragment containing an {@link org.apache.wicket.extensions.markup.html.form.select.SelectOption}. The fragment is
- * a direct child of a select tag. We need this fragment to add a label to a {@link org.apache.wicket.extensions.markup.html.form.select.SelectOption}
- * widget.
+ * a direct child of a select tag. We need this fragment to add a label to a {@link
+ * org.apache.wicket.extensions.markup.html.form.select.SelectOption} widget.
*/
private class OptionFragment extends Fragment {
private static final long serialVersionUID = 1L;
@@ -311,7 +358,7 @@
public OptionFragment(String id, String markupId, InternalSelectOption selectOption) {
super(id, markupId, DynamicDropdownPlugin.this);
SelectOption wicketSelectOption = new SelectOption("option", new Model(selectOption
- .getValue()));
+ .getValue()));
wicketSelectOption.add(new Label("optionLabel", selectOption.getLabel()));
add(wicketSelectOption);
}
Index: addon-cms/src/main/java/org/onehippo/forge/selection/frontend/plugin/AjaxUpdatesAware.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- addon-cms/src/main/java/org/onehippo/forge/selection/frontend/plugin/AjaxUpdatesAware.java (revision )
+++ addon-cms/src/main/java/org/onehippo/forge/selection/frontend/plugin/AjaxUpdatesAware.java (revision )
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2009-2013 Hippo B.V. (http://www.onehippo.com)
+ *
+ * Licensed 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.onehippo.forge.selection.frontend.plugin;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+
+/**
+ * @version $Id: $
+ */
+public interface AjaxUpdatesAware {
+
+ void onAjaxUpdate(AjaxRequestTarget target, String eventId, Object message);
+
+}
Index: addon-cms/src/main/java/org/onehippo/forge/selection/frontend/plugin/Config.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- addon-cms/src/main/java/org/onehippo/forge/selection/frontend/plugin/Config.java (revision 852)
+++ addon-cms/src/main/java/org/onehippo/forge/selection/frontend/plugin/Config.java (revision )
@@ -25,4 +25,6 @@
public final static String SORT_COMPARATOR = "sortComparator";
public final static String SORT_ORDER = "sortOrder";
public final static String SORT_BY = "sortBy";
+ public final static String BROADCAST_EVENT_ID = "broadcastEventId";
+ public final static String RECEIVE_EVENT_ID = "receiveEventId";
}