001 // Copyright 2004, 2005 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014 package org.apache.tapestry.enhance;
015
016 import javassist.CtClass;
017 import org.apache.hivemind.ApplicationRuntimeException;
018 import org.apache.hivemind.service.ClassFab;
019 import org.apache.hivemind.service.ClassFactory;
020 import org.apache.hivemind.service.InterfaceFab;
021 import org.apache.tapestry.event.ResetEventListener;
022
023 /**
024 * Implementation of the hivemind core {@link ClassFactory} service to get around some incompatibilities
025 * the current 1.1.1 implementation of hivemind has with the latest (3.4) version of javassist.
026 */
027 public class ClassFactoryImpl implements ClassFactory, ResetEventListener {
028
029 static final int EXPIRED_CLASS_COUNT = 120;
030
031 /**
032 * ClassPool shared by all modules (all CtClassSource instances).
033 */
034 private HiveMindClassPool _pool = new HiveMindClassPool();
035
036 private CtClassSource _classSource = new CtClassSource(_pool);
037
038 int _classCounter = 0;
039
040 public ClassFab newClass(String name, Class superClass)
041 {
042 try
043 {
044 checkPoolExpiration();
045
046 CtClass ctNewClass = _classSource.newClass(name, superClass);
047
048 return new ClassFabImpl(_classSource, ctNewClass);
049 }
050 catch (Exception ex)
051 {
052 throw new ApplicationRuntimeException(EnhanceMessages.unableToCreateClass(name, superClass, ex), ex);
053 }
054 }
055
056 /** @since 1.1 */
057
058 public InterfaceFab newInterface(String name)
059 {
060 try
061 {
062 checkPoolExpiration();
063
064 CtClass ctNewClass = _classSource.newInterface(name);
065
066 return new InterfaceFabImpl(_classSource, ctNewClass);
067 }
068 catch (Exception ex)
069 {
070 throw new ApplicationRuntimeException(EnhanceMessages.unableToCreateInterface(name, ex), ex);
071 }
072
073 }
074
075 public void resetEventDidOccur()
076 {
077 if (_classCounter >= EXPIRED_CLASS_COUNT)
078 {
079 _classCounter = 0;
080
081 _pool = new HiveMindClassPool();
082 _classSource.setPool(_pool);
083 }
084 }
085
086 void checkPoolExpiration()
087 {
088 _classCounter++;
089 }
090 }