Ignore:
Timestamp:
11/28/18 15:27:56 (6 years ago)
Author:
bln4
Message:

org.expeditee.actions ->
org.exepdtiee.settings.legacy ->

There is a new, slightly improved, way of running actions. The old type of running actions can be used by changing a setting under the legacy category (new settings category). The new way of running actions allows actions to be written to take both the text item on the cursor and the text item that represents the actions.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/expeditee/actions/Actions.java

    r1192 r1195  
    391391         * Performs the given action command. The source frame and item are given
    392392         * because they are required by some actions. Note that the source frame
    393          * does not ahve to be the items parent frame.
     393         * does not have to be the items parent frame.
    394394         *
    395395         * If multiple actions exist with the name command.takeWhile(_ != ' ') then
     
    406406         * @throws Exception
    407407         */
    408         public static Object PerformAction(final Frame source, final Item launcher,
     408        public static Object LegacyPerformAction(final Frame source, final Item launcher,
    409409                        final String command) throws Exception {
     410                MessageBay.displayMessage("Using Legacy code to execute action: " + command);
    410411                final String actionName = getName(command);
    411412                final String parameters = command.substring(actionName.length()).trim();
     
    422423                final String lowercaseName = actionName.toLowerCase();
    423424                final Method firstCanditate = _Actions.get(lowercaseName);
    424                 //      if this is not the name of a method, it may be the name of an agent
     425                // if this is not the name of a method, it may be the name of an agent
    425426                if (firstCanditate == null) {
    426427                        String commandAgent = command.substring(actionName.length()).trim();
     
    475476                // arguments.
    476477                for (final Method canditate : canditates) {
    477                         final Object[] paramObjects = CreateObjects(canditate, source,
     478                        final Object[] paramObjects = LegacyCreateObjects(canditate, source,
    478479                                        launcher, parameters);
    479480                        try {
     
    493494                throw new RuntimeException(errorBuilder.toString());
    494495        }
    495 
     496       
     497
     498        private static Object PerformAction(final Frame source, final Item launcher, final String command, final Item actionItem) throws Exception {
     499                final String actionName = getName(command);
     500                final String parameters = command.substring(actionName.length()).trim();
     501
     502                // Check for protection on frame.
     503                if (ItemUtils.ContainsTag(source.getItems(), "@No" + actionName)) {
     504                        final String errorMsg = "Frame is protected by @No" + actionName
     505                                        + " tag.";
     506                        MessageBay.errorMessage(errorMsg);
     507                        throw new RuntimeException(errorMsg);
     508                }
     509
     510                // Find all canditates. Sort by quantity of arguments.
     511                final String lowercaseName = actionName.toLowerCase();
     512                final Method firstCanditate = _Actions.get(lowercaseName);
     513                // if this is not the name of a method, it may be the name of an agent
     514                if (firstCanditate == null) {
     515                        String commandAgent = command.substring(actionName.length()).trim();
     516                        if(commandAgent.length() == 0 && launcher instanceof Text && launcher.isFloating())
     517                                commandAgent = launcher.getText();
     518                        LaunchAgent(actionName, commandAgent, source, launcher);
     519                        return null;
     520                }
     521                //      need to save the frame if we are navigating away from it so we dont
     522                //      loose changes
     523                if (firstCanditate.getDeclaringClass().getName().equals(NAVIGATIONS_CLASS)) {
     524                        FrameIO.SaveFrame(DisplayController.getCurrentFrame());
     525                }
     526                final List<Method> canditates = new LinkedList<Method>();
     527                canditates.add(firstCanditate);
     528                int i = 0;
     529                while (_Actions.containsKey(lowercaseName + i))
     530                        canditates.add(_Actions.get(lowercaseName + i++));
     531                canditates.sort(new Comparator<Method>() {
     532                        @Override
     533                        public int compare(final Method m1, final Method m2) {
     534                                final int parameterCountDifference = m2.getParameterCount() - m1.getParameterCount();
     535                                if(parameterCountDifference == 0) {
     536                                        final Class<?>[] m1ParamTypes = m1.getParameterTypes();
     537                                        final Class<?>[] m2ParamTypes = m2.getParameterTypes();
     538                               
     539                                        //final ArrayList<Class<?>> typeOrder = Arrays.asList(Integer.TYPE, Double.TYPE, Float.TYPE, String.class);
     540                                        // The above line doesn't compile in Eclipse Mars with the compile set to v1.8
     541                                        // So changed to the following (low-tech) way:
     542                                        ArrayList<Class<?>> typeOrder = new ArrayList<Class<?>>();
     543                                        typeOrder.add(Integer.TYPE);
     544                                        typeOrder.add(Double.TYPE);
     545                                        typeOrder.add(Float.TYPE);
     546                                        typeOrder.add(String.class);
     547                                       
     548                                         for(int i = 0,o = 0; i < m1ParamTypes.length && o < m2ParamTypes.length; i++,o++) {
     549                                                final Class<?> m1ParamType = m1ParamTypes[i];
     550                                                final Class<?> m2ParamType = m2ParamTypes[o];
     551                                                final int m1ParamTypeIndex = typeOrder.indexOf(m1ParamType) != -1 ?
     552                                                                                typeOrder.indexOf(m1ParamType) : typeOrder.size();
     553                                                final int m2ParamTypeIndex = typeOrder.indexOf(m2ParamType) != -1 ?
     554                                                                                typeOrder.indexOf(m2ParamType) : typeOrder.size();
     555                                                final int paramMagnitude = m2ParamTypeIndex - m1ParamTypeIndex;
     556                                                if(paramMagnitude != 0) return paramMagnitude;
     557                                        }
     558                                }
     559                                return parameterCountDifference;
     560                        }
     561                });
     562
     563                // Find best candidate. Start searching with the candidate with most
     564                // arguments.
     565                for (final Method canditate : canditates) {
     566                        final Object[] paramObjects = CreateObjects(canditate, source,
     567                                        launcher, parameters, actionItem);
     568                        try {
     569                                if (paramObjects != null)
     570                                        return canditate.invoke(null, paramObjects);
     571                        } catch (final Exception e) {
     572                                Logger.Log(e);
     573                                e.printStackTrace();
     574                        }
     575                }
     576                assert (canditates.size() > 0);
     577                final String nl = System.getProperty("line.separator");
     578                final StringBuilder errorBuilder = new StringBuilder(
     579                                "Incorrect parameters for " + actionName + nl + "Canditates: ");
     580                for (final Method canditate : canditates)
     581                        errorBuilder.append(canditate + nl);
     582                throw new RuntimeException(errorBuilder.toString());
     583        }
     584       
    496585        // /**
    497586        // * Performs the given action command. The source Frame and Item are given
     
    865954         * @return The created array of Objects
    866955         */
    867         public static Object[] CreateObjects(Method method, Frame source,
     956        public static Object[] LegacyCreateObjects(Method method, Frame source,
    868957                        Item launcher, String values) {
    869958                // The parameter types that should be created from the given String
     
    9271016                return objects;
    9281017        }
     1018       
     1019
     1020        private static Object[] CreateObjects(final Method method, final Frame source, final Item launcher, String values, final Item actionItem) {
     1021                final Class<?>[] paramTypes = method.getParameterTypes();
     1022                final int paramCount = paramTypes.length;
     1023                int ind = 0;
     1024               
     1025                // If the canditate method has no parameters then we have already searched through all canditates with a greater number of parameters, so we can return new Object[0]
     1026                if (paramCount == 0) { return new Object[0]; }
     1027               
     1028                // Resolved parameters
     1029                final Object[] objects = new Object[paramCount];
     1030               
     1031                // If the ind'th parameter is a Frame then the source is the ind'th argument
     1032                if (paramTypes[ind] == Frame.class) { objects[ind++] = source; }
     1033                //Text user_t = ...
     1034               
     1035                // method = setFooAction(Dot i)
     1036                //Item action_i = user_t;
     1037                // If the ind'th parameter is a the same class as launcher then the launcher is the ind'th argument
     1038                //if (paramCount > ind && paramTypes[ind] == launcher.getClass() && Item.class.isAssignableFrom(paramTypes[ind])) { objects[ind++] = launcher; }
     1039                if (paramCount > ind && launcher.getClass().isAssignableFrom(paramTypes[ind])) { objects[ind++] = launcher; }
     1040                // Otherwise, try using the launcher's text as a replacement for values
     1041                else if (launcher != null && launcher.isFloating()) { values = launcher.getText(); }
     1042               
     1043                // If the ind'th parameter is a the same class as actionItem then the actionItem is the ind'th argument.
     1044                if (paramCount > ind && actionItem.getClass().isAssignableFrom(paramTypes[ind])) { objects[ind++] = actionItem; }
     1045               
     1046                // foo(Frame, Item, Item)
     1047                // currentFrame, laucher, actionItem
     1048               
     1049                // foo(Frame, Item, Item, String)
     1050               
     1051                // foo(Frame, Item)
     1052               
     1053                // Parse the remainder of the parameters
     1054                String param = values;
     1055                for (; ind < objects.length; ind++) {
     1056                        // If we are at the last parameter, then try cram the remaining content in as the parameter
     1057                        if (ind == objects.length - 1 && values.length() > 0) {
     1058                                param = values.trim();
     1059                                // The one exception is if we are starting a double quote enclosed string.  In that case, the content following the string (if any) is discarded without the matching process failing.
     1060                                if (param.length() > 0 && param.charAt(0) == '"') {
     1061                                        final int endOfString = param.indexOf('"', 1);
     1062                                        if (endOfString > 0) { param = param.substring(1, endOfString); }
     1063                                }
     1064                        }
     1065                        // Otherwise, strip off the next value.
     1066                        else {
     1067                                param = ParseValue(values);
     1068                                values = RemainingParams(values);
     1069                        }
     1070                        // Attempt to convert the param canditate to an object.  If this fails, we have failed to create a sane list of a variables to match to this method canditate.
     1071                        try {
     1072                                Object o = Conversion.Convert(paramTypes[ind], param);
     1073                                if (o == null) { return null; }
     1074                                objects[ind] = o;
     1075                        } catch (final Exception e) { return null; }
     1076                }
     1077               
     1078                return objects;
     1079        }
     1080
    9291081
    9301082        /**
     
    10411193        }
    10421194
    1043         public static Object PerformActionCatchErrors(Frame current, Item launcher,
     1195        public static Object LegacyPerformActionCatchErrors(Frame current, Item launcher,
    10441196                        String command) {
    10451197                try {
    1046                         return PerformAction(current, launcher, command);
     1198                        return LegacyPerformAction(current, launcher, command);
    10471199                } catch (RuntimeException e) {
    10481200                        e.printStackTrace();
     
    10551207                return null;
    10561208        }
     1209       
     1210
     1211        public static Object PerformActionCatchErrors(final Frame current, final Item launcher, final String command, final Item actionItem) {
     1212                try {
     1213                        return PerformAction(current, launcher, command, actionItem);
     1214                } catch (RuntimeException e) {
     1215                        e.printStackTrace();
     1216                        MessageBay.errorMessage("Action failed: " + e.getMessage());
     1217                } catch (Exception e) {
     1218                        e.printStackTrace();
     1219                        MessageBay.errorMessage("Action failed: "
     1220                                        + e.getClass().getSimpleName());
     1221                }
     1222                return null;
     1223        }
    10571224
    10581225        /**
Note: See TracChangeset for help on using the changeset viewer.