----------------------Options-----------------------------
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.wicket.Component;
import org.apache.wicket.model.IDetachable;
import org.apache.wicket.model.IModel;
import org.odlabs.wiquery.core.javascript.JsScope;
/**
* $Id: Options.java 1714M 2012-01-17 08:38:19Z (local) $
* <p>
* Wraps a set of options possibly defined for a WiQuery { @link Component}.
* </p>
*
* <p>
* By default, Options are rendered as a JavaScript object like this:
*
* <pre>
* {
* option1: 'value1',
* option2: 'value2
* }
* </pre>
*
* This rendering can be customized by creating a { @link IOptionsRenderer}.
* </p>
*
* @author Lionel Armanet
* @author Hielke Hoeve
* @author Ernesto Reinaldo Barreiro
* @since 0.5
*/
public class Options implements IModel<Options>
{
private static final long serialVersionUID = 1L;
private Component owner;
/**
* The internal structure is a map associating each option label with each option
* value.
*/
private final Map<String, Object> options = new LinkedHashMap<String, Object>();
/**
* The { @link IOptionsRenderer} to use.
*/
private IOptionsRenderer optionsRenderer;
/**
* Build a new empty { @link Options} instance that does not bind to a component. This
* does not allow the usage of IComponentAssignedModels as option values.
*/
public Options()
{
this(null);
}
/**
* Build a new empty { @link Options} instance that binds to a component
*/
public Options(Component owner)
{
this.owner = owner;
this.optionsRenderer = DefaultOptionsRenderer.get();
}
public void setOwner(Component owner)
{
if (this.owner != null && this.owner != owner)
throw new IllegalArgumentException(
"Cannot use the same Options for multiple components");
this.owner = owner;
}
/**
* <p>
* Returns if the given option is defined or not.
* </p>
*
* @param key
* the option name.
*/
public boolean containsKey(Object key)
{
return options.containsKey(key);
}
/**
* <p>
* Returns the given option value as a String.
* </p>
*
* @param key
* the option name.
*/
public String get(String key)
{
String ret = getValueFromOptions(key, StringOption.class);
if (ret == null && options.containsKey(key))
ret = options.get(key).toString();
return ret;
}
/**
* <p>
* Returns the given option value.
* </p>
*
* @param key
* the option name.
*/
public Boolean getBoolean(String key)
{
return getValueFromOptions(key, BooleanOption.class);
}
/**
* <p>
* Returns the given option value.
* </p>
*
* @param key
* the option name.
*/
public JsScope getJsScope(String key)
{
return (JsScope) this.options.get(key);
}
/**
* <p>
* Returns the given option value.
* </p>
*
* @param key
* the option name.
* @return the complex option
*/
public IComplexOption getComplexOption(String key)
{
Object object = this.options.get(key);
if (object instanceof IComplexOption)
return (IComplexOption) object;
return null;
}
/**
* <p>
* Returns the given option value.
* </p>
*
* @param key
* the option name.
*/
public Double getDouble(String key)
{
return getValueFromOptions(key, DoubleOption.class);
}
/**
* <p>
* Returns the given option value.
* </p>
*
* @param key
* the option name.
*/
public Float getFloat(String key)
{
return getValueFromOptions(key, FloatOption.class);
}
/**
* <p>
* Returns the given option value.
* </p>
*
* @param key
* the option name.
*/
public Integer getInt(String key)
{
return getValueFromOptions(key, IntegerOption.class);
}
/**
* Returns the JavaScript statement corresponding to options.
*/
public CharSequence getJavaScriptOptions()
{
StringBuilder sb = new StringBuilder();
this.optionsRenderer.renderBefore(sb);
int count = 0;
for (Entry<String, Object> entry : options.entrySet())
{
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof IModelOption< ? >)
value = ((IModelOption< ? >) value).wrapOnAssignment(owner);
boolean isLast = !(count < options.size() - 1);
if (value instanceof JsScope)
{
// Case of a JsScope
sb.append(this.optionsRenderer.renderOption(key, ((JsScope) value).render(), isLast));
}
else if (value instanceof ICollectionItemOptions)
{
// Case of an ICollectionItemOptions
sb.append(this.optionsRenderer.renderOption(key,
((ICollectionItemOptions) value).getJavascriptOption(), isLast));
}
else if (value instanceof IComplexOption)
{
// Case of an IComplexOption
sb.append(this.optionsRenderer.renderOption(key,
((IComplexOption) value).getJavascriptOption(), isLast));
}
else if (value instanceof ITypedOption< ? >)
{
// Case of an ITypedOption
sb.append(this.optionsRenderer.renderOption(key,
((ITypedOption< ? >) value).getJavascriptOption(), isLast));
}
else
{
// Other cases
sb.append(this.optionsRenderer.renderOption(key, value, isLast));
}
count++;
}
this.optionsRenderer.renderAfter(sb);
return sb;
}
/**
* <p>
* Returns the given option value.
* </p>
*
* @param key
* the option name.
* @return the list
*/
public ICollectionItemOptions getListItemOptions(String key)
{
Object object = this.options.get(key);
if (object instanceof ICollectionItemOptions)
return (ICollectionItemOptions) object;
return null;
}
/**
* <p>
* Returns the given option value.
* </p>
*
* @param key
* the option name.
*/
public String getLiteral(String key)
{
return getValueFromOptions(key, LiteralOption.class);
}
/**
* <p>
* Returns the given option value.
* </p>
*
* @param key
* the option name.
*/
public Short getShort(String key)
{
return getValueFromOptions(key, ShortOption.class);
}
/**
* @return true if no options are defined, false otherwise.
*/
public boolean isEmpty()
{
return this.options.isEmpty();
}
private <T, O extends IModelOption<T>> T getValueFromOptions(String key, Class<O> optionClass)
{
Object object = this.options.get(key);
if (optionClass.isInstance(object))
{
O option = optionClass.cast(object);
return option.wrapOnAssignment(owner).getValue();
}
return null;
}
private void putOption(String key, IModelOption< ? > option)
{
options.put(key, option);
}
/**
* <p>
* Put an boolean value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the boolean value.
*/
public Options put(String key, boolean value)
{
putOption(key, new BooleanOption(value));
return this;
}
/**
* <p>
* Put an boolean value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the boolean value.
*/
public Options putBoolean(String key, IModel<Boolean> value)
{
putOption(key, new BooleanOption(value));
return this;
}
/**
* <p>
* Puts an double value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the float double.
*/
public Options put(String key, double value)
{
putOption(key, new DoubleOption(value));
return this;
}
/**
* <p>
* Puts an IModel <Double> value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the float value.
*/
public Options putDouble(String key, IModel<Double> value)
{
putOption(key, new DoubleOption(value));
return this;
}
/**
* <p>
* Puts an float value for the given option name.
* </p>
*
* @param key
* the option name
* @param value
* The float value
* @return
*/
public Options put(String key, float value)
{
putOption(key, new FloatOption(value));
return this;
}
/**
* <p>
* Puts an IModel <Double> value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the float double.
*/
public Options putFloat(String key, IModel<Float> value)
{
putOption(key, new FloatOption(value));
return this;
}
/**
* <p>
* Puts a list of IListItemOption value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the IListItemOption list.
*/
public Options put(String key, ICollectionItemOptions value)
{
options.put(key, value);
return this;
}
/**
* <p>
* Puts a complex option value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the IComplexOption.
*/
public Options put(String key, IComplexOption value)
{
options.put(key, value);
return this;
}
/**
* <p>
* Puts an int value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the int value.
*/
public Options put(String key, int value)
{
putOption(key, new IntegerOption(value));
return this;
}
/**
* <p>
* Puts an int value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the int value.
*/
public Options putInteger(String key, IModel<Integer> value)
{
putOption(key, new IntegerOption(value));
return this;
}
/**
* <p>
* Puts a { @link JsScope} value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the { @link JsScope} value.
*/
public Options put(String key, JsScope value)
{
options.put(key, value);
return this;
}
/**
* <p>
* Puts an short value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the short value.
*/
public Options put(String key, short value)
{
putOption(key, new ShortOption(value));
return this;
}
/**
* <p>
* Puts an short value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the short value.
*/
public Options putShort(String key, IModel<Short> value)
{
putOption(key, new ShortOption(value));
return this;
}
/**
* <p>
* Puts a { @link String} value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the { @link String} value.
*/
public Options put(String key, String value)
{
putOption(key, new StringOption(value));
return this;
}
/**
* <p>
* Puts a { @link String} value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the { @link String} value.
*/
public Options putString(String key, IModel<String> value)
{
putOption(key, new StringOption(value));
return this;
}
/**
* <p>
* Puts a { @link Long} value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the { @link Long} value.
*/
public Options put(String key, long value)
{
putOption(key, new LongOption(value));
return this;
}
/**
* <p>
* Puts a { @link Long} value for the given option name.
* </p>
*
* @param key
* the option name.
* @param value
* the { @link Long} value.
*/
public Options putLong(String key, IModel<Long> value)
{
putOption(key, new LongOption(value));
return this;
}
/**
* <p>
* Puts a { @link String} value as a JavaScript literal for the given name.
* <p>
* Note that the JavaScript resulting from this options will be <code>'value'</code>
* </p>
* </p>
*
* @param key
* the option name.
* @param value
* the { @link LiteralOption} value.
*/
public Options putLiteral(String key, String value)
{
putOption(key, new LiteralOption(value));
return this;
}
/**
* <p>
* Puts a { @link String} value as a JavaScript literal for the given name.
* <p>
* Note that the JavaScript resulting from this options will be <code>'value'</code>
* </p>
* </p>
*
* @param key
* the option name.
* @param value
* the { @link LiteralOption} value.
*/
public Options putLiteral(String key, IModel<String> value)
{
putOption(key, new LiteralOption(value));
return this;
}
/**
* <p>
* Removes an option for a given name.
* </p>
*
* @param key
* the option's key to remove.
*/
public void removeOption(String key)
{
this.options.remove(key);
}
/**
* Sets the renderer to use.
*/
public void setRenderer(IOptionsRenderer optionsRenderer)
{
this.optionsRenderer = optionsRenderer;
}
@Override
public Options getObject()
{
return this;
}
@Override
public void setObject(Options object)
{
throw new UnsupportedOperationException(
"The setObject() function is not supported for object Options.");
}
@Override
public void detach()
{
onDetach(this.options);
}
@SuppressWarnings("unchecked")
private void onDetach(Object detachable)
{
if (detachable instanceof Component)
((Component) detachable).detach();
else if (detachable instanceof IDetachable)
((IDetachable) detachable).detach();
else if (detachable instanceof Map< ? , ? >)
{
for (Map.Entry< ? , ? > entry : ((Map< ? , ? >) detachable).entrySet())
{
onDetach(entry.getKey());
onDetach(entry.getValue());
}
}
else if (detachable instanceof Iterable< ? >)
{
Iterator<Object> iter = ((Iterable<Object>) detachable).iterator();
while (iter.hasNext())
{
onDetach(iter.next());
}
}
}
}
-----------------------------------ResizableJavaScriptResourceReference------------------------------
import org.apache.wicket.markup.head.HeaderItem;
import org.apache.wicket.request.resource.JavaScriptResourceReference;
import org.odlabs.wiquery.core.resources.JavaScriptHeaderItems;
import org.odlabs.wiquery.ui.core.CoreUIJavaScriptResourceReference;
import org.odlabs.wiquery.ui.mouse.MouseJavaScriptResourceReference;
/**
* $Id$
* <p>
* References the JavaScript resource to apply resizable behavior to any HTML element.
* </p>
*
* @author Lionel Armanet
* @since 0.5
*/
public class ResizableJavaScriptResourceReference extends JavaScriptResourceReference
{
// Constants
/** Constant of serialization */
private static final long serialVersionUID = 3423205998397680042L;
/**
* Singleton instance.
*/
private static ResizableJavaScriptResourceReference instance =
new ResizableJavaScriptResourceReference();
/**
* Builds a new instance of {@link ResizableJavaScriptResourceReference}.
*/
private ResizableJavaScriptResourceReference()
{
super(ResizableJavaScriptResourceReference.class, "jquery.ui.resizable.js");
}
/**
* Returns the {@link ResizableJavaScriptResourceReference} instance.
*/
public static ResizableJavaScriptResourceReference get()
{
return instance;
}
@Override
public Iterable< ? extends HeaderItem> getDependencies()
{
return JavaScriptHeaderItems.forReferences(CoreUIJavaScriptResourceReference.get(),
MouseJavaScriptResourceReference.get());
}
}
----------------------------------JsQuery--------------------------------------------------
import java.io.Serializable;
import org.apache.wicket.Component;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.apache.wicket.markup.html.IHeaderContributor;
import org.apache.wicket.request.IRequestHandler;
import org.odlabs.wiquery.core.util.WiQueryUtil;
/**
* $Id: JsQuery.java 1721M 2012-01-17 17:43:37Z (local) $
* <p>
* {@link JsQuery} is the main entry point of WickeXt's JavaScript integration. This class
* is used to link JavaScript to a component and to render it.
* </p>
* <p>
* This class implements the {@link IHeaderContributor} interface, so if you want to
* append the generated JavaScript, just do this:
*
* <pre>
* <code>
* JsQuery jsq = new JsQuery(myComponent);
* jsq.$().chain("css", "border", "1px solid red");
* myComponent.add(new HeaderContributor(jsq));
* </code>
* </pre>
*
* </p>
* <p>
* If you want to generate a statement concerning a component, do it as below:
* <p>
* <code>new JsQuery(yourComponent).$().chain("css", "border", "1px solid red"));</code>
* </p>
* </p>
*
* @author Lionel Armanet
* @since 0.7
*/
public class JsQuery extends Behavior implements Serializable
{
private static final long serialVersionUID = -5351600688981395614L;
/**
* The component attached to the statement.
*/
private Component component;
/**
* The built statement.
*/
private JsStatement statement;
/**
* Creates a new {@link JsQuery} linked to a {@link Component}.
*/
public JsQuery(Component component)
{
super();
this.component = component;
this.component.setOutputMarkupId(true);
}
/**
* Creates a new {@link JsQuery}.
*/
public JsQuery()
{
}
/**
* @return a new {@link JsStatement} initialized with the <code>$</code> statement.
*/
public JsStatement $()
{
return statement = new JsStatement().$(component);
}
/**
* Same as {@link #$()} but with a specified CSS selector. If this {@link JsQuery} is
* linked to a component, the resulting JavaScript code will be
* <p>
* <code>$("#yourComponentId cssSelector")</code>
* </p>
*
* @param selector
* @return
*/
public JsStatement $(String selector)
{
return statement = new JsStatement().$(component, selector);
}
/**
* @return a new {@link JsStatement} initialized with the <code>document</code>
* statement.
*/
public JsStatement document()
{
return statement = new JsStatement().document();
}
@Override
public void renderHead(Component component, IHeaderResponse response)
{
final String js = statement == null ? null : statement.render().toString();
if (js != null && js.trim().length() > 0)
{
response.render(JavaScriptHeaderItem.forReference(WiQueryUtil
.getJQueryResourceReference()));
response.render(OnDomReadyHeaderItem.forScript(js));
}
}
@Override
public final void bind(Component hostComponent)
{
if (hostComponent == null)
{
throw new IllegalArgumentException("Argument hostComponent must be not null");
}
if (component != null && component != hostComponent)
{
throw new IllegalStateException("this kind of handler cannot be attached to "
+ "multiple components; it is already attached to component " + component
+ ", but component " + hostComponent + " wants to be attached too");
}
component = hostComponent;
// call the callback
onBind();
}
/**
* Called when the component was bound to it's host component. You can get the bound
* host component by calling getComponent.
*/
protected void onBind()
{
component.setOutputMarkupId(true);
}
/**
* @return the statement
*/
public JsStatement getStatement()
{
return statement;
}
/**
* FOR FRAMEWORK'S INTERNAL USE ONLY
*/
public void setStatement(JsStatement jsStatement)
{
this.statement = jsStatement;
}
/**
* Adds this statement as Behavior to the component. When the page or ajax request is
* rendered this statement will be added.
*
* @deprecated use {@link Component#add(Behavior...)}.
*/
@Deprecated
public void contribute(Component component)
{
component.add(this);
}
/**
* FOR FRAMEWORK'S INTERNAL USE ONLY
*/
public void renderHead(IHeaderResponse response, IRequestHandler requestHandler)
{
final String js = statement == null ? null : statement.render().toString();
if (js != null && js.trim().length() > 0)
{
response.render(OnDomReadyHeaderItem.forScript(js));
}
}
}