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_16007_BINARY_REQUIRED ) );
72 }
73
74 this.attribute = attribute;
75 }
76
77
78
79
80
81
82
83
84
85 private static byte[] getBytes( InputStream input ) throws IOException
86 {
87 ByteArrayOutputStream result = new ByteArrayOutputStream();
88
89 byte[] buf = new byte[2048];
90 int bytesRead = input.read( buf );
91
92 while ( bytesRead != -1 )
93 {
94 result.write( buf, 0, bytesRead );
95 bytesRead = input.read( buf );
96 }
97
98 result.flush();
99 result.close();
100
101 return result.toByteArray();
102 }
103
104
105
106
107
108
109
110
111
112 private Map<String, Class<?>> loadClasses( byte[] jarBytes ) throws IOException
113 {
114 Map<String, Class<?>> map = new HashMap<>();
115
116 try ( JarInputStream jis = new JarInputStream( new ByteArrayInputStream( jarBytes ) ) )
117 {
118 JarEntry entry;
119 boolean isJar = false;
120
121 while ( ( entry = jis.getNextJarEntry() ) != null )
122 {
123 String fileName = entry.getName();
124 isJar = true;
125
126
127 if ( fileName.endsWith( ".class" ) )
128 {
129 String className = fileName.substring( 0, fileName.length() - ".class".length() ).replace( '/', '.' );
130 byte[] classBytes = getBytes( jis );
131
132 Class<?> clazz = defineClass( className, classBytes, 0, classBytes.length );
133 map.put( className, clazz );
134 }
135 }
136
137 if ( !isJar )
138 {
139 return null;
140 }
141 }
142
143 return map;
144 }
145
146
147
148
149
150 @Override
151 public Class<?> findClass( String name ) throws ClassNotFoundException
152 {
153 byte[] classBytes;
154
155 Value value = attribute.get();
156
157 if ( value.isHumanReadable() )
158 {
159 throw new ClassNotFoundException( I18n.err( I18n.ERR_16008_AT_ACCESS_FAILURE ) );
160 }
161
162 classBytes = value.getBytes();
163
164
165 try
166 {
167 Map<String, Class<?>> classes = loadClasses( classBytes );
168
169 if ( classes == null )
170 {
171
172 return defineClass( name, classBytes, 0, classBytes.length );
173 }
174
175 for ( Map.Entry<String, Class<?>> entry : classes.entrySet() )
176 {
177 if ( entry.getKey().contains( name ) )
178 {
179 return entry.getValue();
180 }
181 }
182 }
183 catch ( IOException ioe )
184 {
185
186 return defineClass( name, classBytes, 0, classBytes.length );
187 }
188
189 return null;
190 }
191 }