How can I check if a class belongs to Java JDK - reflection

I use an external library which return some List<?>.
I need to check if each object of this list is an Object of the JDK (String, int, Integer...).
Is this a proper solution?
List<?> list = externalLibrary.search(...);
for(clazz : list) {
if (clazz.getPackage().getName().startsWith("java.lang"))
// do something different
}
Is there a better one?

Depending on your definition of "object of the JDK" -- which could get quite fuzzy around the edges -- no, this isn't going to do it. The java.lang package is only a tiny part of all the classes included in the JDK.
You might check whether each object was loaded by the same ClassLoader that loaded java.lang.String -- i.e.,
if (theObject.getClass().getClassLoader() == "".getClass().getClassLoader()) ...
In general, a different ClassLoader will be used for system classes vs. application classes.

It is probably OK, just you have to check the following packages:
java
javax
com.sun
sun
probably others...

We use the below class to check if the classes belongs to JDK
public class JDKClass {
private static Set<String> CS = new HashSet<String>();
static {
try {
File file = new File(System.getProperty("java.home"),
"lib/classlist");
BufferedReader r = new BufferedReader(new FileReader(file));
String l;
while (true) {
l = r.readLine();
if (l == null) {
break;
} else {
CS.add(l.replace('/', '.'));
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static boolean contains(String o) {
return CS.contains(o) || o.startsWith("java") || o.startsWith("com.sun")
|| o.startsWith("sun") || o.startsWith("oracle")
|| o.startsWith("org.xml") || o.startsWith("com.oracle");
}
private JDKClass() {
}
}

You can use ClassLoader.getSystemResources and then check from what jar is the class loaded (f.g. if it comes from rt.jar).
You will get URL's such as:
jar:file:/C:/Users/user/.m2/repository/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1.jar!/org/slf4j/impl/StaticLoggerBinder.class
Example code taken from SLF4j:
private static String STATIC_LOGGER_BINDER_PATH =
"org/slf4j/impl/StaticLoggerBinder.class";
private static void singleImplementationSanityCheck() {
try {
ClassLoader loggerFactoryClassLoader = LoggerFactory.class
.getClassLoader();
Enumeration paths;
if (loggerFactoryClassLoader == null) {
paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
} else {
paths = loggerFactoryClassLoader
.getResources(STATIC_LOGGER_BINDER_PATH);
}
List implementationList = new ArrayList();
while (paths.hasMoreElements()) {
URL path = (URL) paths.nextElement();
implementationList.add(path);
}
....
}

Personally I like class loader base answer. But it will return true also on StringBuilder. If you want to more narrow definition that is only "built-in" types, you can try to evaluate whether this is primitive type (such as int) or wrapper type (such as Integer) or String. You can write something like this:
import java.util.Map;
import java.util.TreeMap;
public class Utils {
private static Map<String, Class<?>> SUBST_MAP = new TreeMap<String, Class<?>>();
private static Map<String, Class<?>> SIMPLE_MAP = new TreeMap<String, Class<?>>();
static {
SUBST_MAP.put(Byte.class.getName(), Byte.TYPE);
SUBST_MAP.put(Short.class.getName(), Short.TYPE);
SUBST_MAP.put(Integer.class.getName(), Integer.TYPE);
SUBST_MAP.put(Long.class.getName(), Long.TYPE);
SUBST_MAP.put(Float.class.getName(), Float.TYPE);
SUBST_MAP.put(Double.class.getName(), Double.TYPE);
SUBST_MAP.put(Boolean.class.getName(), Boolean.TYPE);
SUBST_MAP.put(Character.class.getName(), Character.TYPE);
SIMPLE_MAP.put(String.class.getName(), Boolean.TRUE);
}
/**
* Gets the the class type of the types of the argument.
*
* if substPrimitiveWrapper is true,
* then if there is argument, that represent primitive type wrapper (such as Integer),
* then it will be substituted to primitive type (such as int).
* else no substitution will be done.
*
* #param arg object.
* #param substPrimitiveWrapper - wheteher to do primitive type substitution.
* #retrun class type.
*/
public static Class<?> getClassType(Object arg, boolean substPrimitiveWrapper){
Class<?> classType = null;
String className = null;
Class<?> substClass = null;
if(arg != null ){
//making default classType
classType = arg.getClass();
if(substPrimitiveWrapper){
className = classType.getName();
substClass = (Class<?>)SUBST_MAP.get(className);
if(substClass != null){
classType = substClass;
}
}
}
return classType;
}
/**
* This method consider JDK type any primitive type, wrapper class or String.
*
*
* #param arg object
* #return where arg is JDK type or now.
*/
public static boolean isJDKClass(Object arg){
Class<?> classType = getClassType(arg, true);
boolean isJDKClass = false;
if(classType!=null){
//if(String.class.equals(classType)){
// isJDKClass = true; //this is String, note that String is final
//}
assert classType!=null;
String className = classType.getName();
Boolean isFound = (Boolean)SIMPLE_MAP.get(className);
if(Boolean.TRUE.equals(isFound)){
isJDKClass = true; //this is predefined class
}
boolean isPrimitiveType = classType.isPrimitive();
if(isPrimitiveType){
isJDKClass = true; //this is primitive type or wrapper class
}
}
return isJDKClass;
}
}
You can also optionally add support for such classes like java.math.BigDecimal, java.util.Date, java.sql.Timestamp. Note, however, that they are not final, so I assumed that if somebody extended them even in the trivial way, it will not be considered as JDK class.

I think an easier solution is to thing of the problem this way:
write a method to identify all classes that are defined by you. In most cases, all user defined classes follow a pattern like com.something.something. Then if they do not belong to com.something.something, it is a JDK class

Related

HashSet and Dictionary in TypeScript: export of Interface

I think I need some feedback on my collection classes - still learning typescript and javascript and these implementations can surely be improved. I am looking forward to any suggestion. I think I do use the generic types in a useful way, any advice here would be appreciated.
The answer I am looking for most is removing the duplicate IHashTable definition from the end of both snippets and moving it to its own file, I cannot get that done it seems. I am even unsure if this IS an interface in the first place. It compiles and works this way, as far as I can see.
The collection types are incomplete and only define the basic most function at the moment. Once I am sure I use the language and its features correct the other functions should not be too difficult.
Here is my HashSet:
import { IHashable } from "./IHashable"
export class HashSet<T extends IHashable> {
private _items: HashTable<T>;
public constructor() {
this._items = {};
}
public Add(key: T): void {
let str: string = key.GetHash();
if (this._items[str] == null) {
this._items[str] = key;
}
else {
throw new RangeError("Key '" + str + "' already exists.");
}
}
public Contains(key: T): boolean {
let str: string = key.GetHash();
return this._items[str] != null;
}
}
interface HashTable<T> {
[key: string]: T;
}
I wonder if I can avoid the checking-before-adding in a way. The javascript-dictionary this relies on does allow duplicates, so to avoid them there is no other way than to check myself?
This is my Dictionary:
import { IHashable } from "./IHashable"
export class Dictionary<T1 extends IHashable, T2> {
private _items: HashTable<KeyValuePair<T1, T2>>;
public constructor() {
this._items = {};
}
public Add(key: T1, value: T2) {
let str: string = key.GetHash();
if (this._items[str] == null) {
let kvp: KeyValuePair<T1, T2> = new KeyValuePair(key, value);
this._items[str] = kvp;
}
else {
throw new RangeError("Key '" + str + "' already exists.");
}
}
public ContainsKey(key: T1): boolean {
let str: string = key.GetHash();
return this._items[str] != null;
}
public Get(key: T1): T2 {
let str: string = key.GetHash();
let kvp: KeyValuePair<T1, T2> = this._items[str];
if (kvp == null) throw new RangeError("Key '" + str + "' not found")
return kvp.Value;
}
}
export class KeyValuePair<T1 extends IHashable, T2> {
private _key: T1;
private _value: T2;
public get Key(): T1 { return this._key; }
public get Value(): T2 { return this._value; }
public constructor(key: T1, value: T2) {
this._key = key;
this._value = value;
}
}
interface HashTable<T> {
[key: string]: T;
}
Both rely on a definition of IHashable (hashABLE and hashTABLE: I should find other names.)
export interface IHashable {
GetHash(): string;
}
The dictionary looks a bit strange, it "wraps" my dictionary into a new type KeyValuePair and then uses this in the javascript dictionary. What I hope to gain by doing this is get my own type for key, in and out, as long as it offers a string by which it can be indexed. - No idea if that makes sense or is completly wrong.
What I am missing is the count of items in the collection, a way to remove items, and a way to iterate over the keys and the values.
Regarding iterating over I will post another question with my implementation of a list and a ForEach over it, hoping iterating the keys or values might be possible in the same way.
Probably the most important question I forgot here: How could the GetHash-Method be build for an own class? I was going to have a static number on my classes, and count up by 1 in the constructor before assign this number to each instance. This would guarantee uniqueness... is there something better?
Thanks for any tip!
Ralf

Constraints on parameters in api interface

I've declared an API call in an interface and was wondering if it is possible to put constraints on some of the parameters. The API I'm accessing has these constraints as well and would like to enforce them in my program.
#GET("/recipes/search")
Call<RecipeResponse> getRecipes(
#Query("cuisine") String cuisine,
#Query("diet") String diet,
#Query("excludeIngredients") String excludeIngredients,
#Query("intolerances") String intolerances,
#Query("number") Integer number,
#Query("offset") Integer offset,
#Query("query") String query,
#Query("type") String type
);
How can I do this?
I know that it is possible to do this with POST request, and passing along an object via the RequestBody through the #Body annotation. Can I do this with a GET request too, where information is passed via the query string?
Thanks!
I think I ended up finding a solution. I've made a class SearchRecipeRequest in which I declare all possible parameters as class variables. In the setters I do the data validation such as checking for null on parameters that are required, or min/max value constraints on integers as specified by the endpoint. I then made a SearchRecipeRequestBuilder class to build such an object like so to make it easier to deal with all those possible parameters:
public class SearchRecipeRequestBuilder {
private String _cuisine = null,
_diet = null,
_excludeIngredients = null,
_intolerances = null,
_query = null,
_type = null;
private Integer _number = null,
_offset = null;
public SearchRecipeRequestBuilder() {}
public SearchRecipeRequest buildRequest() {
return new SearchRecipeRequest(_cuisine, _diet, _excludeIngredients, _intolerances, _number, _offset, _query, _type);
}
public SearchRecipeRequestBuilder cuisine(String cuisine) {
_cuisine = cuisine;
return this;
}
public SearchRecipeRequestBuilder diet(String diet) {
_diet = diet;
return this;
}
public SearchRecipeRequestBuilder excludeIngredients(String excludeIngredients) {
_excludeIngredients = excludeIngredients;
return this;
}
public SearchRecipeRequestBuilder intolerances(String intolerances) {
_intolerances = intolerances;
return this;
}
public SearchRecipeRequestBuilder query(String query) {
_query = query;
return this;
}
public SearchRecipeRequestBuilder type(String type) {
_type = type;
return this;
}
public SearchRecipeRequestBuilder number(Integer number) {
_number = number;
return this;
}
public SearchRecipeRequestBuilder offset(Integer offset) {
_offset = offset;
return this;
}
}
Which allows me to build the request like so:
SearchRecipeRequest request = new SearchRecipeRequestBuilder()
.query("burger")
.buildRequest();
I then pass along that object to a different function that knows how to use the request object to pass it along to the API.
That's how I'm doing it right now, if someone has a better way I'd love to hear it. :)
I got the idea to use the Builder pattern from a different StackOverflow question: Managing constructors with many parameters in Java.

AspectJ - Is is possible to extend an enum's value?

Say I have an enum
public enum E {A,B,C}
Is it possible to add another value, say D, by AspectJ?
After googling around, it seems that there used to be a way to hack the private static field $VALUES, then call the constructor(String, int) by reflection, but seems not working with 1.7 anymore.
Here are several links:
http://www.javaspecialists.eu/archive/Issue161.html (provided by #WimDeblauwe )
and this: http://www.jroller.com/VelkaVrana/entry/modify_enum_with_reflection
Actually, I recommend you to refactor the source code, maybe adding a collection of valid region IDs to each enumeration value. This should be straightforward enough for subsequent merging if you use Git and not some old-school SCM tool like SVN.
Maybe it would even make sense to use a dynamic data structure altogether instead of an enum if it is clear that in the future the list of commands is dynamic. But that should go into the upstream code base. I am sure the devs will accept a good patch or pull request if prepared cleanly.
Remember: Trying to avoid refactoring is usually a bad smell, a symptom of an illness, not a solution. I prefer solutions to symptomatic workarounds. Clean code rules and software craftsmanship attitude demand that.
Having said the above, now here is what you can do. It should work under JDK 7/8 and I found it on Jérôme Kehrli's blog (please be sure to add the bugfix mentioned in one of the comments below the article).
Enum extender utility:
package de.scrum_master.util;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import sun.reflect.ConstructorAccessor;
import sun.reflect.FieldAccessor;
import sun.reflect.ReflectionFactory;
public class DynamicEnumExtender {
private static ReflectionFactory reflectionFactory =
ReflectionFactory.getReflectionFactory();
private static void setFailsafeFieldValue(Field field, Object target, Object value)
throws NoSuchFieldException, IllegalAccessException
{
// let's make the field accessible
field.setAccessible(true);
// next we change the modifier in the Field instance to
// not be final anymore, thus tricking reflection into
// letting us modify the static final field
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
int modifiers = modifiersField.getInt(field);
// blank out the final bit in the modifiers int
modifiers &= ~Modifier.FINAL;
modifiersField.setInt(field, modifiers);
FieldAccessor fa = reflectionFactory.newFieldAccessor(field, false);
fa.set(target, value);
}
private static void blankField(Class<?> enumClass, String fieldName)
throws NoSuchFieldException, IllegalAccessException
{
for (Field field : Class.class.getDeclaredFields()) {
if (field.getName().contains(fieldName)) {
AccessibleObject.setAccessible(new Field[] { field }, true);
setFailsafeFieldValue(field, enumClass, null);
break;
}
}
}
private static void cleanEnumCache(Class<?> enumClass)
throws NoSuchFieldException, IllegalAccessException
{
blankField(enumClass, "enumConstantDirectory"); // Sun (Oracle?!?) JDK 1.5/6
blankField(enumClass, "enumConstants"); // IBM JDK
}
private static ConstructorAccessor getConstructorAccessor(Class<?> enumClass, Class<?>[] additionalParameterTypes)
throws NoSuchMethodException
{
Class<?>[] parameterTypes = new Class[additionalParameterTypes.length + 2];
parameterTypes[0] = String.class;
parameterTypes[1] = int.class;
System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length);
return reflectionFactory.newConstructorAccessor(enumClass .getDeclaredConstructor(parameterTypes));
}
private static Object makeEnum(Class<?> enumClass, String value, int ordinal, Class<?>[] additionalTypes, Object[] additionalValues)
throws Exception
{
Object[] parms = new Object[additionalValues.length + 2];
parms[0] = value;
parms[1] = Integer.valueOf(ordinal);
System.arraycopy(additionalValues, 0, parms, 2, additionalValues.length);
return enumClass.cast(getConstructorAccessor(enumClass, additionalTypes).newInstance(parms));
}
/**
* Add an enum instance to the enum class given as argument
*
* #param <T> the type of the enum (implicit)
* #param enumType the class of the enum to be modified
* #param enumName the name of the new enum instance to be added to the class
*/
#SuppressWarnings("unchecked")
public static <T extends Enum<?>> void addEnum(Class<T> enumType, String enumName) {
// 0. Sanity checks
if (!Enum.class.isAssignableFrom(enumType))
throw new RuntimeException("class " + enumType + " is not an instance of Enum");
// 1. Lookup "$VALUES" holder in enum class and get previous enum
// instances
Field valuesField = null;
Field[] fields = enumType.getDeclaredFields();
for (Field field : fields) {
if (field.getName().contains("$VALUES")) {
valuesField = field;
break;
}
}
AccessibleObject.setAccessible(new Field[] { valuesField }, true);
try {
// 2. Copy it
T[] previousValues = (T[]) valuesField.get(enumType);
List<T> values = new ArrayList<T>(Arrays.asList(previousValues));
// 3. build new enum
T newValue = (T) makeEnum(
enumType, // The target enum class
enumName, // THE NEW ENUM INSTANCE TO BE DYNAMICALLY ADDED
values.size(), new Class<?>[] {}, // could be used to pass values to the enum constuctor if needed
new Object[] {} // could be used to pass values to the enum constuctor if needed
);
// 4. add new value
values.add(newValue);
// 5. Set new values field
setFailsafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(enumType, 0)));
// 6. Clean enum cache
cleanEnumCache(enumType);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage(), e);
}
}
}
Sample application & enum:
package de.scrum_master.app;
/** In honour of "The Secret of Monkey Island"... ;-) */
public enum Command {
OPEN, CLOSE, PUSH, PULL, WALK_TO, PICK_UP, TALK_TO, GIVE, USE, LOOK_AT, TURN_ON, TURN_OFF
}
package de.scrum_master.app;
public class Server {
public void executeCommand(Command command) {
System.out.println("Executing command " + command);
}
}
package de.scrum_master.app;
public class Client {
private Server server;
public Client(Server server) {
this.server = server;
}
public void issueCommand(String command) {
server.executeCommand(
Command.valueOf(
command.toUpperCase().replace(' ', '_')
)
);
}
public static void main(String[] args) {
Client client = new Client(new Server());
client.issueCommand("use");
client.issueCommand("walk to");
client.issueCommand("undress");
client.issueCommand("sleep");
}
}
Console output with original enum:
Executing command USE
Executing command WALK_TO
Exception in thread "main" java.lang.IllegalArgumentException: No enum constant de.scrum_master.app.Command.UNDRESS
at java.lang.Enum.valueOf(Enum.java:236)
at de.scrum_master.app.Command.valueOf(Command.java:1)
at de.scrum_master.app.Client.issueCommand(Client.java:12)
at de.scrum_master.app.Client.main(Client.java:22)
Now you can either add an aspect with an advice executed after the enum class was loaded or just call this manually in your application before extended enum values are to be used for the first time. Here I am showing how it can be done in an aspect.
Enum extender aspect:
package de.scrum_master.aspect;
import de.scrum_master.app.Command;
import de.scrum_master.util.DynamicEnumExtender;
public aspect CommandExtender {
after() : staticinitialization(Command) {
System.out.println(thisJoinPoint);
DynamicEnumExtender.addEnum(Command.class, "UNDRESS");
DynamicEnumExtender.addEnum(Command.class, "SLEEP");
DynamicEnumExtender.addEnum(Command.class, "WAKE_UP");
DynamicEnumExtender.addEnum(Command.class, "DRESS");
}
}
Console output with extended enum:
staticinitialization(de.scrum_master.app.Command.<clinit>)
Executing command USE
Executing command WALK_TO
Executing command UNDRESS
Executing command SLEEP
Et voilà! ;-)

Retrieve property by name

I'm struggling to create a dynamic view generation utility for javafx. I've a handful of Classes that have ObjectProperty's or StringProperty's I'd like to create a ComboBox for each property and bind directly the combo selected value to the Class property by name if possible. Is there some helper or method in any of the javafx.beans.binding that would allow me to specify an Object and a String name and retrieve the property. Or to just retrieve a list of properties. I have a method now that takes the string and matches it to the property by name but it requires I have a case for each property on the object, which on an object with 20+ properties is a lot of duplicate code.
I guess to specify I'm looking for javafx.bean.property as a return type.
You can always use Java Reflection.
Getting a list of properties
for (Method method : Node.class.getMethods()) {
String name = method.getName();
if (name.endsWith("Property")) {
Type returnType = method.getReturnType();
String propName = name.replace("Property", "");
System.out.println(propName + " : " + returnType);
}
}
Here is reflective method for binding and example:
public class ReflectiveBind extends Application {
/**
* Reflection call for code like
* slider1.valueProperty().bindBidirectional(slider2.valueProperty());
*
* #param bindee Node which you want to be changed by binding
* #param propertyName name of the property, e.g. width
* #param bindTarget Node which you want to be updated by binding
*/
private static void bind(Object bindee, String propertyName, Object bindTarget) throws Exception {
// here we get slider1.valueProperty()
Method methodForBindee = bindee.getClass().getMethod(propertyName + "Property", (Class[]) null);
Object bindableObj = methodForBindee.invoke(bindee);
// here we get slider2.valueProperty()
Method methodForBindTarget = bindTarget.getClass().getMethod(propertyName + "Property", (Class[]) null);
Object bindTargetObj = methodForBindTarget.invoke(bindTarget);
// here we call bindBidirectional: slider1.valueProperty().bindBidirectional(slider2.valueProperty())
Method bindMethod = bindableObj.getClass().getMethod("bindBidirectional", Property.class);
bindMethod.invoke(bindableObj, bindTargetObj);
}
#Override
public void start(Stage stage) {
Slider slider1 = new Slider();
Slider slider2 = new Slider();
VBox root = new VBox(20);
root.getChildren().addAll(slider1, slider2);
stage.setScene(new Scene(root, 200, 100));
stage.show();
try {
//same call as slider1.valueProperty().bindBidirectional(slider2.valueProperty());
bind(slider1, "value", slider2);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) { launch(); }
}
Check out apache commons bean utils
http://commons.apache.org/beanutils/
You say you want to...
Get the value of the property:
http://commons.apache.org/beanutils/api/org/apache/commons/beanutils/BeanUtils.html#getProperty%28java.lang.Object,%20java.lang.String%29
Get List of Properties:
http://commons.apache.org/beanutils/api/org/apache/commons/beanutils/BeanUtils.html#describe%28java.lang.Object%29
Lots of other useful methods there, and for UI work they are particularly convenient since many of them return the string form which is what you want to display.
If you want objects rather than strings use the PropertUtils class instead
Get the value of the property (not as a string)
http://commons.apache.org/beanutils/v1.8.3/apidocs/org/apache/commons/beanutils/PropertyUtils.html#getProperty%28java.lang.Object,%20java.lang.String%29
Get list of properties:
http://commons.apache.org/beanutils/v1.8.3/apidocs/org/apache/commons/beanutils/PropertyUtils.html#describe%28java.lang.Object%29

Elegant way to bind html radio buttons <=> Java enums <=> mysql enums in Play?

The Goal is to have a list of options (that a user can chose through radio buttons) in one place(for eg: a yaml config file). No other place should have this list hard-coded
I've done something similar to create select elements, and I think enums worked just fine. Doing radio buttons should be very similar. I've set it up so that the labels can be defined in the messages file. I'm going to try to excerpt the relevant portions from my larger auto-form-generation code (using FastTags) the best I can. It's a bit heavy for this one case but it makes sense in the larger system.
I use the tag like #{form.selector 'order.status' /}, which looks find the variable named order in the template, sees that status is declared as public Status status, and then goes to find all the values of the Status enum and generate options for them in the select element.
First, I use a FieldContext object which just contains a bunch of info that's used by the other code to determine what to generate along with some utility methods:
public class FieldContext {
public final Map<?,?> args;
public final ExecutableTemplate template;
public final int fromLine;
public Class clazz = null;
public Field field = null;
public Object object = null;
public Object value = null;
private Map<String,String> attrs = new HashMap<String,String>();
private Map<String,Boolean> printed = new HashMap<String,Boolean>();
private List<Option> options;
...
Then I have this in another helper class (its info gets added to the FieldContext):
public List<Option> determineOptions(FieldContext context) {
List<Option> options = new ArrayList<Option>();
if (context.field.getType().isEnum()) {
for (Object option : context.field.getType().getEnumConstants()) {
options.add(new Option(option.toString(), Message.get(option.toString())));
}
}
return options;
}
then the tag declaration is
public static void _selector(Map<?,?> args, Closure body, PrintWriter out, ExecutableTemplate template, int fromLine) {
String field_name = args.get("arg").toString();
TagContext.current().data.put("name", field_name);
SelectHelper helper = HelperFactory.getHelper(SelectHelper.class);
try {
FieldContext context = new FieldContext(field_name, args, template, fromLine);
helper.autoconfigure(context);
TagContext.current().data.put("selected", helper.determineValue(context));
out.print("<div class=\"formutil-field formutil-selector\">");
out.print("<label for=\"" + context.getAttr("id") + "\">");
out.print(helper.findOrCreateLabel(context));
out.print("</label>");
out.print("<select");
context.printAttribute(out, "id", "name");
out.print(">");
if (context.hasOptions()) {
for (Option option : context.getOptions()) {
out.print("<option value=\"" + option.value + "\">" + option.label + "</option>");
}
}
out.print("</select>");
context.printErrorIfPresent(out);
context.printValidationHints(out);
out.println("</div>");
}
...
}

Resources