Skip to content
This repository has been archived by the owner on Oct 18, 2022. It is now read-only.

Commit

Permalink
Added support for annotating List<String> fields with @ListedByEnum,
Browse files Browse the repository at this point in the history
e.g.
@ListedByEnum(type = MyEnum.class)
List<String> strings;

The CRUD admin will render a listbox with multiselect for this field
configuration. 

Change-Id: I405c4d2a88c1f4e0676c2b693314fecaa50a72ed
  • Loading branch information
henper committed Aug 16, 2012
1 parent 1c81c65 commit a1811b5
Show file tree
Hide file tree
Showing 8 changed files with 289 additions and 6 deletions.
5 changes: 5 additions & 0 deletions src/main/java/burrito/client/crud/CrudFieldResolver.java
Expand Up @@ -28,6 +28,7 @@
import burrito.client.crud.generic.fields.DateField;
import burrito.client.crud.generic.fields.DisplayableMethodField;
import burrito.client.crud.generic.fields.EmbeddedListField;
import burrito.client.crud.generic.fields.EnumListField;
import burrito.client.crud.generic.fields.FileField;
import burrito.client.crud.generic.fields.ImageField;
import burrito.client.crud.generic.fields.IntegerListField;
Expand All @@ -47,6 +48,7 @@
import burrito.client.crud.input.CrudInputFieldImpl;
import burrito.client.crud.input.DateCrudInputField;
import burrito.client.crud.input.EmbeddedListInputField;
import burrito.client.crud.input.EnumListInputField;
import burrito.client.crud.input.FileCrudInputField;
import burrito.client.crud.input.ImageCrudInputField;
import burrito.client.crud.input.IntegerInputField;
Expand Down Expand Up @@ -135,6 +137,9 @@ public static CrudInputField createInputField(CrudField field, CrudServiceAsync
return new SearchListField(relationField, service);
}
}
if (field instanceof EnumListField) {
return new EnumListInputField((EnumListField) field);
}
if (field instanceof ImageField) {
return new ImageCrudInputField((ImageField) field);
}
Expand Down
@@ -0,0 +1,53 @@
/**
* Copyright 2011 Henric Persson (henric.persson@gmail.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 burrito.client.crud.generic.fields;

import java.util.List;

import burrito.client.crud.generic.CrudField;

/**
* A {@link CrudField} representating a selection of enums
*
* @author henper
*
*/
@SuppressWarnings("serial")
public class EnumListField extends StringListField {

private String enumClassName;

public EnumListField() {
super();
// default constructor
}

public EnumListField(List<String> strings, String enumClassName) {
super(strings);
this.setEnumClassName(enumClassName);
}

public void setEnumClassName(String enumClassName) {
this.enumClassName = enumClassName;
}

public String getEnumClassName() {
return enumClassName;
}

}
58 changes: 58 additions & 0 deletions src/main/java/burrito/client/crud/input/EnumListInputField.java
@@ -0,0 +1,58 @@
/**
* Copyright 2011 Henric Persson (henric.persson@gmail.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 burrito.client.crud.input;


import java.util.List;

import burrito.client.crud.generic.CrudField;
import burrito.client.crud.generic.fields.EnumListField;
import burrito.client.crud.widgets.EnumListWidget;

import com.google.gwt.user.client.ui.Widget;

public class EnumListInputField implements CrudInputField<List<String>> {

private EnumListField field;
private EnumListWidget widget;

@SuppressWarnings("unchecked")
public EnumListInputField(EnumListField field) {
this.field = field;
widget = new EnumListWidget(field.isRequired(), field.getEnumClassName());
load((List<String>) field.getValue());
}

public CrudField getCrudField() {
field.setValue(getValue());
return field;
}

public Widget getDisplayWidget() {
return widget;
}

public List<String> getValue() {
return widget.getValue();
}

public void load(List<String> values) {
widget.setValue(values);
}

}
2 changes: 2 additions & 0 deletions src/main/java/burrito/client/crud/labels/CrudMessages.java
Expand Up @@ -118,6 +118,8 @@ public interface CrudMessages extends Messages {

String embeddedItemAtLeastOne(String embeddedTypeInSingular);

String atLeastOne();

String linkIsRequired();

String chooseLinkType();
Expand Down
162 changes: 162 additions & 0 deletions src/main/java/burrito/client/crud/widgets/EnumListWidget.java
@@ -0,0 +1,162 @@
/**
* Copyright 2011 Henric Persson (henric.persson@gmail.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 burrito.client.crud.widgets;

import java.util.ArrayList;
import java.util.List;

import burrito.client.crud.CrudService;
import burrito.client.crud.CrudServiceAsync;
import burrito.client.crud.labels.CrudLabelHelper;
import burrito.client.crud.labels.CrudMessages;
import burrito.client.widgets.validation.HasValidators;
import burrito.client.widgets.validation.InputFieldValidator;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;

public class EnumListWidget extends Composite implements HasValidators {
private VerticalPanel wrapper = new VerticalPanel();
private CrudMessages labels = GWT.create(CrudMessages.class);
private boolean required;
private Label validationError = new Label(labels.atLeastOne());
private ListBox lb = new ListBox(true);
private List<String> pendingValue;
private CrudServiceAsync service = GWT.create(CrudService.class);
private boolean enumsLoaded = false;
private final String enumClassName;



/**
* Create a new linked entity widget.
*
* @param required
* true if at least one link must be specified
* @param allowMultiple
* true if multiple links can be entered. In this case, use
* getValues() to fetch a list of links. IF false, use getValue()
* to get the only link.
*/
public EnumListWidget(boolean required, String enumClassName) {
this.required = required;
this.enumClassName = enumClassName;
validationError.addStyleName("validationError");
validationError.setVisible(false);
wrapper.add(lb);
wrapper.add(validationError);
initWidget(wrapper);
addStyleName("k5-EnumListWidget");
loadEnumValues();
}

private void loadEnumValues() {
service.getEnumListValues(enumClassName, new AsyncCallback<List<String>>() {

@Override
public void onSuccess(List<String> enumValues) {
renderListBox(enumValues);
}

@Override
public void onFailure(Throwable caught) {
throw new RuntimeException(caught);
}
});
}

protected void renderListBox(List<String> enumValues) {
String enumClassNameWithUnderscore = enumClassName.replace(".", "_");
for (String enumValue : enumValues) {
lb.addItem(CrudLabelHelper.getString(enumClassNameWithUnderscore + "_" + enumValue), enumValue);
}
enumsLoaded = true;
if (pendingValue != null) {
renderSelectedValues(pendingValue);
pendingValue = null;
}
}

private void renderSelectedValues(List<String> values) {
for (int i = 0; i < lb.getItemCount(); i++) {
String val = lb.getValue(i);
lb.setItemSelected(i, values.contains(val));
}
}

public void addInputFieldValidator(InputFieldValidator validator) {
throw new UnsupportedOperationException();
}

public void setValidationError(String validationError) {
throw new UnsupportedOperationException();
}

public boolean validate() {
validationError.setVisible(false);
if (required && getValue() == null) {
validationError.setVisible(true);
return false;
}
return true;
}

/**
* Gets the list of selected items
*
* @return
*/
public List<String> getValue() {
if (pendingValue != null) {
return pendingValue;
}
List<String> values = new ArrayList<String>();
for (int i = 0; i < lb.getItemCount(); i++) {
if (lb.isItemSelected(i)) {
values.add(lb.getValue(i));
}
}
return values;
}

/**
* Sets the list of selected items
*
* @param json
*/
public void setValue(List<String> value) {
if (enumsLoaded) {
renderSelectedValues(value);
} else {
//Set pending and wait for enum load
pendingValue = value;
}

}


@Override
public void highlight() {
lb.setFocus(true);
}

}
13 changes: 7 additions & 6 deletions src/main/java/burrito/services/CrudServiceImpl.java
Expand Up @@ -22,7 +22,6 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -77,6 +76,7 @@
import burrito.client.crud.generic.fields.DateField;
import burrito.client.crud.generic.fields.DisplayableMethodField;
import burrito.client.crud.generic.fields.EmbeddedListField;
import burrito.client.crud.generic.fields.EnumListField;
import burrito.client.crud.generic.fields.FileField;
import burrito.client.crud.generic.fields.ImageField;
import burrito.client.crud.generic.fields.IntegerField;
Expand Down Expand Up @@ -434,7 +434,7 @@ public Long save(CrudEntityDescription desc, Long clonedFromId) throws FieldValu
}
}

@SuppressWarnings("unchecked")
@SuppressWarnings({ "unchecked", "rawtypes" })
private void updateEntityFromDescription(Object entity,
CrudEntityDescription desc, Class<?> clazz) {
for (CrudField field : desc.getFields()) {
Expand All @@ -449,19 +449,16 @@ private void updateEntityFromDescription(Object entity,
}

Field privField = EntityUtil.getField(clazz, field.getName());
@SuppressWarnings("rawtypes")
Class fieldType = privField.getType();

if (value != null && field instanceof ListedByEnumField && (Enum.class.isAssignableFrom(fieldType))) {
ListedByEnumField fieldEnum = (ListedByEnumField) field;
String className = fieldEnum.getTypeClassName();
@SuppressWarnings("rawtypes")
Class enumClass = Class.forName(className);

value = Enum.valueOf(enumClass, (String) value);
}


privField.setAccessible(true);
privField.set(entity, value);

Expand Down Expand Up @@ -720,7 +717,7 @@ public CrudField processStandardCrud(Field field, Object entity)
} else if (clazz == List.class) {
ParameterizedType pType = (ParameterizedType) field
.getGenericType();
Type type = pType.getActualTypeArguments()[0];
Class type = (Class) pType.getActualTypeArguments()[0];

if (field.isAnnotationPresent(EmbeddedBy.class)) {
EmbeddedBy embeddedBy = field.getAnnotation(EmbeddedBy.class);
Expand All @@ -736,6 +733,10 @@ public CrudField processStandardCrud(Field field, Object entity)
} else if (type.equals(String.class) && field.isAnnotationPresent(Link.class)) {
crud = new LinkListField((List<String>) field.get(entity));

} else if (field.isAnnotationPresent(ListedByEnum.class)) {
ListedByEnum annot = field.getAnnotation(ListedByEnum.class);
crud = new EnumListField((List<String>) field.get(entity), annot.type().getName());

} else if (type.equals(String.class)) {
crud = new StringListField((List<String>) field.get(entity));

Expand Down
Expand Up @@ -63,6 +63,7 @@ noEmbeddedItemsAdded=No {0} have been added
deleteEmbeddedItem=Delete selected items. The deletion is not saved until you press the Save button.
embeddedItemsDeleted={1} {0} deleted
embeddedItemAtLeastOne=You must add at least one {0}
atLeastOne=You must select at least one
linkIsRequired=You must add at least one link
chooseLinkType=Choose link type
createNewLink=Create new link
Expand Down
Expand Up @@ -89,6 +89,7 @@ noEmbeddedItemsAdded=Inga {0} tillagda
deleteEmbeddedItem=Tar bort markerade rader. Glöm inte att spara efter radering.
embeddedItemsDeleted={1} {0} raderade
embeddedItemAtLeastOne=Du måste lägga till minst en {0}
atLeastOne=Du måste välja minst en
linkIsRequired=Du måste välja en länk
chooseLinkType=Välj länktyp
createNewLink=Skapa ny länk
Expand Down

0 comments on commit a1811b5

Please sign in to comment.