001    /*
002      Copyright (C) 2003 <laurent@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.idGen;
019    
020    import org.aopalliance.intercept.ConstructorInvocation;
021    import org.aopalliance.intercept.MethodInvocation;
022    import org.apache.log4j.Logger;
023    import org.objectweb.jac.core.AspectComponent;
024    import org.objectweb.jac.core.Collaboration;
025    import org.objectweb.jac.core.Interaction;
026    import org.objectweb.jac.core.NameRepository;
027    import org.objectweb.jac.core.Wrapper;
028    import org.objectweb.jac.core.rtti.ClassItem;
029    import org.objectweb.jac.core.rtti.FieldItem;
030    import org.objectweb.jac.util.Log;
031    
032    public class IdGenAC extends AspectComponent {
033        static Logger logger = Logger.getLogger("idgen");
034    
035            public static final String COUNTER = "IdGenAC.COUNTER";
036            public static final String ID_FIELD = "IdGenAC.ID_FIELD";
037    
038            public void genId(ClassItem cl, String counter, String fieldName) {
039                    cl.setAttribute(COUNTER, counter);
040                    cl.setAttribute(ID_FIELD, cl.getField(fieldName));
041                    pointcut(
042                            "ALL",
043                            cl.getName(),
044                            "CONSTRUCTORS",
045                            IdGenWrapper.class.getName(),
046                            null,
047                            false);
048            }
049    
050            Counters counters;
051            protected Counters getCounters() {
052                    if (counters == null) {
053                            if (countersName != null) {
054                                    counters =
055                                            (Counters) NameRepository.get().getObject(countersName);
056                                    if (counters == null) {
057                                            logger.error("IdGenAC: No object named " + countersName);
058                                    }
059                            }
060                    }
061                    return counters;
062            }
063    
064            String countersName = "counters#0";
065            public void setCountersName(String countersName) {
066                    this.countersName = countersName;
067            }
068    
069            public class IdGenWrapper extends Wrapper {
070                    public IdGenWrapper(AspectComponent ac) {
071                            super(ac);
072                    }
073    
074                    public Object genId(Interaction interaction) {
075                            Object result = proceed(interaction);
076                            logger.debug("generating id for " + interaction.wrappee);
077                            ClassItem cl = interaction.getClassItem();
078                            FieldItem field = (FieldItem) cl.getAttribute(ID_FIELD);
079                            if (Collaboration.get().getAttribute("PersistenceAC.RESTORE")
080                                    == null) {
081                                    String counterName = (String) cl.getAttribute(COUNTER);
082                                    Counters counters = getCounters();
083                                    if (counters != null) {
084                                            long id = counters.genId(counterName);
085                                            logger.debug("    -> " + id);
086                                            try {
087                                                    if (field.getType() == String.class)
088                                                            field.setThroughWriter(
089                                                                    interaction.wrappee,
090                                                                    Long.toString(id));
091                                                    else
092                                                            field.setThroughWriter(
093                                                                    interaction.wrappee,
094                                                                    new Long(id));
095                                            } catch (IllegalAccessException e) {
096                                                    logger.error(
097                                                            "Failed to to set field " + field
098                                                                    + " for " + interaction.wrappee);
099                                            }
100                                    } else {
101                                            logger.debug("    No counters object");
102                                    }
103                            } else {
104                                    logger.debug("    skipping id generation for " + interaction.wrappee);
105                            }
106                            return result;
107                    }
108    
109                    public Object invoke(MethodInvocation invocation) throws Throwable {
110                            throw new Exception("This wrapper does not support invocation interception.");
111                    }
112    
113                    public Object construct(ConstructorInvocation invocation)
114                            throws Throwable {
115                            return genId((Interaction) invocation);
116                    }
117            }
118    }