/* * Copyright (C) 2011 Nicolas Peransin. All rights reserved. * Use is subject to license terms. */ package org.mypsycho.swing.app.reflect; import java.util.Arrays; import java.util.List; import javax.swing.Action; import org.mypsycho.beans.Injection; import org.mypsycho.beans.InjectionContext; import org.mypsycho.beans.converter.AbstractTypeConverter; import org.mypsycho.swing.app.Application; import org.mypsycho.swing.app.ResourceManager; import org.mypsycho.swing.app.beans.AbstractTypedAction; import org.mypsycho.swing.app.beans.ApplicationAction; import org.mypsycho.swing.app.beans.ProxyAction; /** * Create an javax.swing.Action object. * <p> * if the value starts with '->', action is proxied to the following expression * otherwize an ApplicationAction object is created. * </p> * * @author Peransin Nicolas */ public class ActionConverter extends AbstractTypeConverter { public static final String REDIRECT_PREFIX = "->"; public ActionConverter() { super(Action.class, AbstractTypedAction.class); } /* (non-Javadoc) * @see com.psycho.beans.converter.TypeConverter#convert(java.lang.Class, java.lang.String, java.lang.Object) */ @Override public Object convert(Class<?> expected, String value, Object context) throws IllegalArgumentException { InjectionContext iContext = (InjectionContext) context; ResourceManager manager = (ResourceManager) iContext.getInjector(); String strategy = ""; Object actionContainer = iContext.getRoot(); boolean implicit = (value == null); if (implicit) { value = fixImplicitName(iContext); } try { if (value.startsWith(REDIRECT_PREFIX)) { strategy = "proxy"; String path = value.substring(REDIRECT_PREFIX.length()); Action action = (Action) manager.getProperty(actionContainer, path); return new ProxyAction(action); } else { strategy = "reflection"; Application app = manager.getApplication(); return new ApplicationAction(app, value, actionContainer, iContext.getLocale()); } } catch (Exception e) { return reThrow("Invalid " + strategy + " action '" + value + "' for " + actionContainer.getClass().getName(), e); } } // Those name cannot be elected for implicit name static final List<String> IGNORED_IMPLICIT_NAMES = Arrays.asList("action"); /** * Try to find a name using the injection path * * @param context the injection context * @return found name or null */ private String fixImplicitName(InjectionContext context) { for (Injection i = context.getInjection(); i != null; i = i.getParent()) { Object id = i.getId(); if (!(id instanceof String)) { continue; // } if (!IGNORED_IMPLICIT_NAMES.contains(id)) { return (String) id; } } throw new IllegalArgumentException("No name for action " + context.getInjection()); } }