001    /*
002      Copyright (C) 2001-2003 Renaud Pawlak <renaud@aopsys.com>
003    
004      This program is free software; you can redistribute it and/or modify
005      it under the terms of the GNU Lesser General Public License as
006      published by the Free Software Foundation; either version 2 of the
007      License, or (at your option) any later version.
008    
009      This program is distributed in the hope that it will be useful,
010      but WITHOUT ANY WARRANTY; without even the implied warranty of
011      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012      GNU Lesser General Public License for more details.
013    
014      You should have received a copy of the GNU Lesser General Public License
015      along with this program; if not, write to the Free Software
016      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
017    
018    package org.objectweb.jac.aspects.confirmation;
019    
020    import org.aopalliance.intercept.ConstructorInvocation;
021    import org.aopalliance.intercept.MethodInvocation;
022    import org.apache.log4j.Logger;
023    import org.objectweb.jac.aspects.gui.DisplayContext;
024    import org.objectweb.jac.aspects.gui.GuiAC;
025    import org.objectweb.jac.core.AspectComponent;
026    import org.objectweb.jac.core.Display;
027    import org.objectweb.jac.core.Interaction;
028    import org.objectweb.jac.core.Wrapper;
029    import org.objectweb.jac.core.rtti.AbstractMethodItem;
030    import org.objectweb.jac.core.rtti.ClassRepository;
031    import org.objectweb.jac.core.rtti.NamingConventions;
032    
033    /**
034     * The confirmation aspect implementation (allows the user to add
035     * confirmation popups before committing. */
036    
037    public class ConfirmationAC
038        extends AspectComponent
039        implements ConfirmationConf 
040    {
041        static final Logger logger = Logger.getLogger("confirmation");
042    
043        static String cancellationMessage = "invocation was cancelled by the user";
044        public void confirm(String classes, String methods, String objects) {
045            pointcut(
046                objects,
047                classes,
048                methods,
049                new ConfirmationWrapper(this),
050                "catchCancellation");
051        }
052    
053        public void confirm(String classes, String methods, String objects, String message) {
054            pointcut(
055                objects,
056                classes,
057                methods,
058                new ConfirmationWrapper(this,message),
059                "catchCancellation");
060        }
061    
062        /**
063         * A confirmation wrapper that wraps methods to show a confirmation
064         * message box before actually performing the call. */
065    
066        public class ConfirmationWrapper extends Wrapper {
067    
068            String message;
069    
070            public ConfirmationWrapper(AspectComponent ac, String message) {
071                super(ac);
072                this.message = message;
073            }
074    
075            public ConfirmationWrapper(AspectComponent ac) {
076                super(ac);
077                this.message = null;
078            }
079    
080            public Object invoke(MethodInvocation invocation) throws Throwable {
081                return confirm((Interaction) invocation);
082            }
083    
084            public Object construct(ConstructorInvocation invocation)
085                throws Throwable {
086                throw new Exception("This wrapper does not support constructor wrapping");
087            }
088    
089            /** The wrapping method. */
090            public Object confirm(Interaction interaction)
091                throws OperationCanceledException 
092            {
093                logger.debug("confirm " + interaction);
094                DisplayContext context =
095                    (DisplayContext) this.attr(GuiAC.DISPLAY_CONTEXT);
096                logger.debug("  context=" + context);
097                AbstractMethodItem method = interaction.method;
098                if (context != null) {
099                    Display display = context.getDisplay();
100                    String actualMessage = message;
101                    if (actualMessage == null) {
102                        if (method.isRemover()) {
103                            actualMessage =
104                                "Do you really want to remove "
105                                + NamingConventions.textForName(
106                                    ClassRepository.get().getClass(interaction.args[0]).getShortName())
107                                + " '"
108                                + GuiAC.toString(interaction.args[0])
109                                + "' from "
110                                + NamingConventions.textForName(
111                                    method.getRemovedCollections()[0].getName())
112                                + " of "
113                                + NamingConventions.textForName(
114                                    interaction.getClassItem().getShortName())
115                                + " '"
116                                + GuiAC.toString(interaction.wrappee)
117                                + "' ?";
118                        } else {
119                            actualMessage =
120                                "Do you really want to "
121                                + NamingConventions.textForName(
122                                    interaction.method.getName())
123                                + (interaction.method.isStatic()
124                                   ? ""
125                                   : (" for '" + GuiAC.toString(interaction.wrappee)) + "'")
126                                + " ?";
127                        }
128                    }
129    
130                    if (!display.showMessage(actualMessage, "Confirmation", true, true, false)) {
131                        throw new OperationCanceledException(interaction);
132                    }
133                }
134                return interaction.proceed();
135            }
136    
137            /** The exception handler. */
138            public void catchCancellation(OperationCanceledException e) {
139                System.out.println("Catching exception: " + e);
140            }
141    
142        }
143    
144    }
145    
146    class OperationCanceledException extends Exception {
147        public OperationCanceledException(Interaction interaction) {
148            super("Operation cancelled: " + interaction.method);
149        }
150    }