/*
 * JBoss, Home of Professional Open Source
 * Copyright 2008, Red Hat, Inc. and/or its affiliates, and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,  
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jboss.weld.bean.proxy.util;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;

import org.jboss.weld.exceptions.WeldException;
import org.jboss.weld.logging.messages.BeanMessage;
import org.jboss.weld.serialization.spi.ProxyServices;

/**
 * A default implementation of the {@link ProxyServices} which simply use the
 * corresponding information from the proxy type. An exception is made for
 * {@code java.*} and {@code javax.*} packages which are often associated with
 * the system classloader and a more privileged ProtectionDomain.
 * 
 * @author David Allen
 */
public class SimpleProxyServices implements ProxyServices
{

   public ClassLoader getClassLoader(Class<?> type)
   {
      SecurityManager sm = System.getSecurityManager();
      if (sm != null) {
          return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
              public ClassLoader run() {
                  return Thread.currentThread().getContextClassLoader();
              }
          });
      } else {
          return Thread.currentThread().getContextClassLoader();
      }
//      if (type.getName().startsWith("java"))
//      {
//         return this.getClass().getClassLoader();
//      }
//      else
//      {
//         return type.getClassLoader();
//      }
   }

   public ProtectionDomain getProtectionDomain(Class<?> type)
   {
      if (type.getName().startsWith("java"))
      {
         return this.getClass().getProtectionDomain();
      }
      else
      {
         return type.getProtectionDomain();
      }
   }

   public void cleanup()
   {
      // This implementation requires no cleanup

   }

   public Object wrapForSerialization(Object proxyObject)
   {
      // Simply use our own replacement object for proxies
      return new SerializableProxy(proxyObject);
   }

   public Class<?> loadProxySuperClass(final String className)
   {
      try
      {
         return (Class<?>) AccessController.doPrivileged(new PrivilegedExceptionAction<Object>()
         {
            public Object run() throws Exception
            {
               //ClassLoader cl = Thread.currentThread().getContextClassLoader();
               ClassLoader cl = getClassLoader(this.getClass());
               return Class.forName(className, true, cl);
            }
         });
      }
      catch (PrivilegedActionException pae)
      {
         throw new WeldException(BeanMessage.CANNOT_LOAD_CLASS, className, pae.getException());
      }
   }

}

@@ -1636,16 +1636,22 @@
 sLoader(
+final 
 Class%3C?%3E
@@ -1739,20 +1739,25 @@
 != null)
+%0A     
  %7B%0A
- 
         
@@ -1829,21 +1829,28 @@
 oader%3E()
+%0A        
  %7B%0A
-  
         
@@ -1877,22 +1877,31 @@
 er run()
- %7B%0A
+%0A         
    
+%7B%0A
         
@@ -1918,40 +1918,11 @@
 urn 
-Thread.currentThread().getContex
+_ge
 tCla
@@ -1926,32 +1926,36 @@
 ClassLoader(
+type
 );%0A     
          %7D%0A 
@@ -1934,32 +1934,41 @@
 der(type);%0A     
+       %7D%0A
          %7D%0A     
@@ -1965,47 +1965,164 @@
    %7D
+);
 %0A     
+ %7D%0A
      
-%7D);%0A      %7D else %7B
+ else%0A      %7B%0A         return _getClassLoader(type);%0A      %7D      %0A   %7D%0A%0A   private ClassLoader _getClassLoader(Class%3C?%3E type)
 %0A   
+%7B%0A
       
+//
  ret
@@ -2173,26 +2173,16 @@
 ader();%0A
-      %7D%0A//
       if
@@ -2218,26 +2218,24 @@
 java%22))%0A
-//
       %7B%0A
 //      
@@ -2218,34 +2218,32 @@
 java%22))%0A      %7B%0A
-//
          return 
@@ -2276,26 +2276,24 @@
 ader();%0A
-//
       %7D%0A
 //      
@@ -2284,18 +2284,16 @@
       %7D%0A
-//
       el
@@ -2299,18 +2299,16 @@
 lse%0A
-//
       %7B%0A
 //  
@@ -2303,18 +2303,16 @@
       %7B%0A
-//
         
@@ -2342,18 +2342,16 @@
 ader();%0A
-//
       %7D%0A
@@ -3153,16 +3153,17 @@
       //
+ 
 ClassLoa
@@ -3170,16 +3170,34 @@
 der cl =
+%0A               //
  Thread.

revert simple proxy services to be symmetric