1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.ldap.schema.loader;
21
22
23 import java.io.ByteArrayInputStream;
24 import java.io.IOException;
25 import java.util.HashMap;
26 import java.util.Map;
27 import java.util.jar.JarEntry;
28 import java.util.jar.JarInputStream;
29
30 import org.apache.directory.api.i18n.I18n;
31 import org.apache.directory.api.ldap.model.entry.Attribute;
32 import org.apache.directory.api.ldap.model.entry.Value;
33 import org.apache.directory.api.ldap.model.exception.LdapException;
34 import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
35 import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
36 import java.io.ByteArrayOutputStream;
37 import java.io.InputStream;
38
39
40
41
42
43
44
45 public class AttributeClassLoader extends ClassLoader
46 {
47
48 private Attribute attribute;
49
50
51
52
53
54 public AttributeClassLoader()
55 {
56 super( AttributeClassLoader.class.getClassLoader() );
57 }
58
59
60
61
62
63
64
65
66 public void setAttribute( Attribute attribute ) throws LdapException
67 {
68 if ( attribute.isHumanReadable() )
69 {
70 throw new LdapInvalidAttributeValueException( ResultCodeEnum.CONSTRAINT_VIOLATION,
71 I18n.err( I18n.ERR_10001 ) );
72 }
73
74 this.attribute = attribute;
75 }
76
77
78
79
80
81 private static byte[] getBytes( InputStream input ) throws IOException
82 {
83 ByteArrayOutputStream result = new ByteArrayOutputStream();
84
85 byte[] buf = new byte[2048];
86 int bytesRead = input.read( buf );
87
88 while ( bytesRead != -1 )
89 {
90 result.write( buf, 0, bytesRead );
91 bytesRead = input.read( buf );
92 }
93
94 result.flush();
95 result.close();
96
97 return result.toByteArray();
98 }
99
100
101 private Map<String, Class<?>> loadClasses( byte[] jarBytes ) throws IOException
102 {
103 Map<String, Class<?>> map = new HashMap<>();
104
105 try ( JarInputStream jis = new JarInputStream( new ByteArrayInputStream( jarBytes ) ) )
106 {
107 JarEntry entry;
108 boolean isJar = false;
109
110 while ( ( entry = jis.getNextJarEntry() ) != null )
111 {
112 String fileName = entry.getName();
113 isJar = true;
114
115
116 if ( fileName.endsWith( ".class" ) )
117 {
118 String className = fileName.substring( 0, fileName.length() - ".class".length() ).replace( '/', '.' );
119 byte[] classBytes = getBytes( jis );
120
121 Class<?> clazz = defineClass( className, classBytes, 0, classBytes.length );
122 map.put( className, clazz );
123 }
124 }
125
126 if ( !isJar )
127 {
128 return null;
129 }
130 }
131
132 return map;
133 }
134
135
136
137
138 @Override
139 public Class<?> findClass( String name ) throws ClassNotFoundException
140 {
141 byte[] classBytes;
142
143 Value<?> value = attribute.get();
144
145 if ( value.isHumanReadable() )
146 {
147 throw new ClassNotFoundException( I18n.err( I18n.ERR_10002 ) );
148 }
149
150 classBytes = value.getBytes();
151
152
153 try
154 {
155 Map<String, Class<?>> classes = loadClasses( classBytes );
156
157 if ( classes == null )
158 {
159
160 return defineClass( name, classBytes, 0, classBytes.length );
161 }
162
163 for ( Map.Entry<String, Class<?>> entry : classes.entrySet() )
164 {
165 if ( entry.getKey().contains( name ) )
166 {
167 return entry.getValue();
168 }
169 }
170 }
171 catch ( IOException ioe )
172 {
173
174 return defineClass( name, classBytes, 0, classBytes.length );
175 }
176
177 return null;
178 }
179 }