View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.javaflow.stores;
18  
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.Iterator;
22  import org.apache.bcel.Repository;
23  import org.apache.bcel.util.ClassLoaderRepository;
24  import org.apache.commons.javaflow.bytecode.transformation.ResourceTransformer;
25  import org.apache.commons.javaflow.bytecode.transformation.bcel.BcelClassTransformer;
26  import org.apache.commons.jci.stores.MemoryResourceStore;
27  import org.apache.commons.jci.stores.ResourceStore;
28  import org.apache.commons.jci.stores.TransactionalResourceStore;
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  
32  /**
33   * Due to the BCEL dependency handling all
34   * classes have to be store first and then
35   * be rewritten. Otherwise we could just
36   * delegate to the TransformingResourceStore
37   * 
38   * @author tcurdt
39   */
40  public final class JavaflowResourceStore extends TransactionalResourceStore {
41  
42      private final static Log log = LogFactory.getLog(JavaflowResourceStore.class);
43  
44      private final TransformingResourceStore tstore;
45      private final Collection changes = new ArrayList();
46      
47      public JavaflowResourceStore() {
48          this(new MemoryResourceStore());
49      }
50      
51      public JavaflowResourceStore(final ResourceStore pStore) {
52          super(pStore);
53          tstore = new TransformingResourceStore(
54                  pStore,
55                  new ResourceTransformer[] { new BcelClassTransformer() }
56                  );
57          Repository.setRepository(new ClassLoaderRepository(this.getClass().getClassLoader()));
58      }
59  
60      public void write(final String pResourceName, final byte[] pResourceData) {
61          super.write(pResourceName, pResourceData);
62          changes.add(pResourceName);
63      }
64  
65      public void onStart() {
66          changes.clear();
67      }
68  
69      public void onStop() {
70          if (changes.size() > 0) {
71              log.debug("rewriting"  + changes);
72              
73              for (Iterator it = changes.iterator(); it.hasNext();) {
74                  final String clazzName = (String) it.next();
75                  try {
76                      final byte[] oldClazz = super.read(clazzName);
77                      
78                      if (oldClazz == null) {
79                          throw new ClassNotFoundException("could not find " + clazzName);
80                      }
81                      
82                      tstore.write(clazzName, oldClazz);
83                      
84                      log.debug("rewrote " + clazzName);
85                  } catch (ClassNotFoundException e) {
86                      log.error("", e);
87                  }
88              }
89              
90              changes.clear();
91          }
92      }
93  }