001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019 package org.apache.felix.framework.util;
020
021 import java.io.*;
022 import java.lang.reflect.*;
023 import java.net.*;
024 import java.security.*;
025 import java.util.HashMap;
026 import java.util.Hashtable;
027
028 import org.osgi.framework.BundleActivator;
029 import org.osgi.framework.BundleContext;
030
031 /**
032 * <p>
033 * This is a utility class to centralize all action that should be performed
034 * in a <tt>doPrivileged()</tt> block. To perform a secure action, simply
035 * create an instance of this class and use the specific method to perform
036 * the desired action. When an instance is created, this class will capture
037 * the security context and will then use that context when checking for
038 * permission to perform the action. Instances of this class should not be
039 * passed around since they may grant the receiver a capability to perform
040 * privileged actions.
041 * </p>
042 **/
043 public class SecureAction
044 {
045 private static final ThreadLocal m_actions = new ThreadLocal()
046 {
047 public Object initialValue()
048 {
049 return new Actions();
050 }
051 };
052
053 protected static transient int BUFSIZE = 4096;
054
055 private AccessControlContext m_acc = null;
056
057 public SecureAction()
058 {
059 if (System.getSecurityManager() != null)
060 {
061 try
062 {
063 Actions actions = (Actions) m_actions.get();
064 actions.set(Actions.INITIALIZE_CONTEXT, null);
065 m_acc = (AccessControlContext) AccessController.doPrivileged(actions);
066 }
067 catch (PrivilegedActionException ex)
068 {
069 throw (RuntimeException) ex.getException();
070 }
071 }
072 else
073 {
074 m_acc = AccessController.getContext();
075 }
076 }
077
078 public String getSystemProperty(String name, String def)
079 {
080 if (System.getSecurityManager() != null)
081 {
082 try
083 {
084 Actions actions = (Actions) m_actions.get();
085 actions.set(Actions.GET_PROPERTY_ACTION, name, def);
086 return (String) AccessController.doPrivileged(actions, m_acc);
087 }
088 catch (PrivilegedActionException ex)
089 {
090 throw (RuntimeException) ex.getException();
091 }
092 }
093 else
094 {
095 return System.getProperty(name, def);
096 }
097 }
098
099 public ClassLoader getParentClassLoader(ClassLoader loader)
100 {
101 if (System.getSecurityManager() != null)
102 {
103 try
104 {
105 Actions actions = (Actions) m_actions.get();
106 actions.set(Actions.GET_PARENT_CLASS_LOADER_ACTION, loader);
107 return (ClassLoader) AccessController.doPrivileged(actions, m_acc);
108 }
109 catch (PrivilegedActionException ex)
110 {
111 throw (RuntimeException) ex.getException();
112 }
113 }
114 else
115 {
116 return loader.getParent();
117 }
118 }
119
120 public ClassLoader getSystemClassLoader()
121 {
122 if (System.getSecurityManager() != null)
123 {
124 try
125 {
126 Actions actions = (Actions) m_actions.get();
127 actions.set(Actions.GET_SYSTEM_CLASS_LOADER_ACTION);
128 return (ClassLoader) AccessController.doPrivileged(actions, m_acc);
129 }
130 catch (PrivilegedActionException ex)
131 {
132 throw (RuntimeException) ex.getException();
133 }
134 }
135 else
136 {
137 return ClassLoader.getSystemClassLoader();
138 }
139 }
140
141 public ClassLoader getClassLoader(Class clazz)
142 {
143 if (System.getSecurityManager() != null)
144 {
145 try
146 {
147 Actions actions = (Actions) m_actions.get();
148 actions.set(Actions.GET_CLASS_LOADER_ACTION, clazz);
149 return (ClassLoader) AccessController.doPrivileged(actions, m_acc);
150 }
151 catch (PrivilegedActionException ex)
152 {
153 throw (RuntimeException) ex.getException();
154 }
155 }
156 else
157 {
158 return clazz.getClassLoader();
159 }
160 }
161
162 public Class forName(String name) throws ClassNotFoundException
163 {
164 if (System.getSecurityManager() != null)
165 {
166 try
167 {
168 Actions actions = (Actions) m_actions.get();
169 actions.set(Actions.FOR_NAME_ACTION, name);
170 return (Class) AccessController.doPrivileged(actions, m_acc);
171 }
172 catch (PrivilegedActionException ex)
173 {
174 if (ex.getException() instanceof ClassNotFoundException)
175 {
176 throw (ClassNotFoundException) ex.getException();
177 }
178 throw (RuntimeException) ex.getException();
179 }
180 }
181 else
182 {
183 return Class.forName(name);
184 }
185 }
186
187 public URL createURL(String protocol, String host,
188 int port, String path, URLStreamHandler handler)
189 throws MalformedURLException
190 {
191 if (System.getSecurityManager() != null)
192 {
193 try
194 {
195 Actions actions = (Actions) m_actions.get();
196 actions.set(Actions.CREATE_URL_ACTION, protocol, host,
197 new Integer(port), path, handler);
198 return (URL) AccessController.doPrivileged(actions, m_acc);
199 }
200 catch (PrivilegedActionException ex)
201 {
202 if (ex.getException() instanceof MalformedURLException)
203 {
204 throw (MalformedURLException) ex.getException();
205 }
206 throw (RuntimeException) ex.getException();
207 }
208 }
209 else
210 {
211 return new URL(protocol, host, port, path, handler);
212 }
213 }
214
215 public URL createURL(URL context, String spec, URLStreamHandler handler)
216 throws MalformedURLException
217 {
218 if (System.getSecurityManager() != null)
219 {
220 try
221 {
222 Actions actions = (Actions) m_actions.get();
223 actions.set(Actions.CREATE_URL_WITH_CONTEXT_ACTION, context,
224 spec, handler);
225 return (URL) AccessController.doPrivileged(actions, m_acc);
226 }
227 catch (PrivilegedActionException ex)
228 {
229 if (ex.getException() instanceof MalformedURLException)
230 {
231 throw (MalformedURLException) ex.getException();
232 }
233 throw (RuntimeException) ex.getException();
234 }
235 }
236 else
237 {
238 return new URL(context, spec, handler);
239 }
240 }
241
242 public Process exec(String command) throws IOException
243 {
244 if (System.getSecurityManager() != null)
245 {
246 try
247 {
248 Actions actions = (Actions) m_actions.get();
249 actions.set(Actions.EXEC_ACTION, command);
250 return (Process) AccessController.doPrivileged(actions, m_acc);
251 }
252 catch (PrivilegedActionException ex)
253 {
254 throw (RuntimeException) ex.getException();
255 }
256 }
257 else
258 {
259 return Runtime.getRuntime().exec(command);
260 }
261 }
262
263 public String getAbsolutePath(File file)
264 {
265 if (System.getSecurityManager() != null)
266 {
267 try
268 {
269 Actions actions = (Actions) m_actions.get();
270 actions.set(Actions.GET_ABSOLUTE_PATH_ACTION, file);
271 return (String) AccessController.doPrivileged(actions, m_acc);
272 }
273 catch (PrivilegedActionException ex)
274 {
275 throw (RuntimeException) ex.getException();
276 }
277 }
278 else
279 {
280 return file.getAbsolutePath();
281 }
282 }
283
284 public boolean fileExists(File file)
285 {
286 if (System.getSecurityManager() != null)
287 {
288 try
289 {
290 Actions actions = (Actions) m_actions.get();
291 actions.set(Actions.FILE_EXISTS_ACTION, file);
292 return ((Boolean) AccessController.doPrivileged(actions, m_acc))
293 .booleanValue();
294 }
295 catch (PrivilegedActionException ex)
296 {
297 throw (RuntimeException) ex.getException();
298 }
299 }
300 else
301 {
302 return file.exists();
303 }
304 }
305
306 public boolean isFileDirectory(File file)
307 {
308 if (System.getSecurityManager() != null)
309 {
310 try
311 {
312 Actions actions = (Actions) m_actions.get();
313 actions.set(Actions.FILE_IS_DIRECTORY_ACTION, file);
314 return ((Boolean) AccessController.doPrivileged(actions, m_acc))
315 .booleanValue();
316 }
317 catch (PrivilegedActionException ex)
318 {
319 throw (RuntimeException) ex.getException();
320 }
321 }
322 else
323 {
324 return file.isDirectory();
325 }
326 }
327
328 public boolean mkdir(File file)
329 {
330 if (System.getSecurityManager() != null)
331 {
332 try
333 {
334 Actions actions = (Actions) m_actions.get();
335 actions.set(Actions.MAKE_DIRECTORY_ACTION, file);
336 return ((Boolean) AccessController.doPrivileged(actions, m_acc))
337 .booleanValue();
338 }
339 catch (PrivilegedActionException ex)
340 {
341 throw (RuntimeException) ex.getException();
342 }
343 }
344 else
345 {
346 return file.mkdir();
347 }
348 }
349
350 public boolean mkdirs(File file)
351 {
352 if (System.getSecurityManager() != null)
353 {
354 try
355 {
356 Actions actions = (Actions) m_actions.get();
357 actions.set(Actions.MAKE_DIRECTORIES_ACTION, file);
358 return ((Boolean) AccessController.doPrivileged(actions, m_acc))
359 .booleanValue();
360 }
361 catch (PrivilegedActionException ex)
362 {
363 throw (RuntimeException) ex.getException();
364 }
365 }
366 else
367 {
368 return file.mkdirs();
369 }
370 }
371
372 public File[] listDirectory(File file)
373 {
374 if (System.getSecurityManager() != null)
375 {
376 try
377 {
378 Actions actions = (Actions) m_actions.get();
379 actions.set(Actions.LIST_DIRECTORY_ACTION, file);
380 return (File[]) AccessController.doPrivileged(actions, m_acc);
381 }
382 catch (PrivilegedActionException ex)
383 {
384 throw (RuntimeException) ex.getException();
385 }
386 }
387 else
388 {
389 return file.listFiles();
390 }
391 }
392
393 public boolean renameFile(File oldFile, File newFile)
394 {
395 if (System.getSecurityManager() != null)
396 {
397 try
398 {
399 Actions actions = (Actions) m_actions.get();
400 actions.set(Actions.RENAME_FILE_ACTION, oldFile, newFile);
401 return ((Boolean) AccessController.doPrivileged(actions, m_acc))
402 .booleanValue();
403 }
404 catch (PrivilegedActionException ex)
405 {
406 throw (RuntimeException) ex.getException();
407 }
408 }
409 else
410 {
411 return oldFile.renameTo(newFile);
412 }
413 }
414
415 public InputStream getFileInputStream(File file) throws IOException
416 {
417 if (System.getSecurityManager() != null)
418 {
419 try
420 {
421 Actions actions = (Actions) m_actions.get();
422 actions.set(Actions.GET_FILE_INPUT_ACTION, file);
423 return (InputStream) AccessController.doPrivileged(actions, m_acc);
424 }
425 catch (PrivilegedActionException ex)
426 {
427 if (ex.getException() instanceof IOException)
428 {
429 throw (IOException) ex.getException();
430 }
431 throw (RuntimeException) ex.getException();
432 }
433 }
434 else
435 {
436 return new FileInputStream(file);
437 }
438 }
439
440 public OutputStream getFileOutputStream(File file) throws IOException
441 {
442 if (System.getSecurityManager() != null)
443 {
444 try
445 {
446 Actions actions = (Actions) m_actions.get();
447 actions.set(Actions.GET_FILE_OUTPUT_ACTION, file);
448 return (OutputStream) AccessController.doPrivileged(actions, m_acc);
449 }
450 catch (PrivilegedActionException ex)
451 {
452 if (ex.getException() instanceof IOException)
453 {
454 throw (IOException) ex.getException();
455 }
456 throw (RuntimeException) ex.getException();
457 }
458 }
459 else
460 {
461 return new FileOutputStream(file);
462 }
463 }
464
465 public InputStream getURLConnectionInputStream(URLConnection conn)
466 throws IOException
467 {
468 if (System.getSecurityManager() != null)
469 {
470 try
471 {
472 Actions actions = (Actions) m_actions.get();
473 actions.set(Actions.GET_URL_INPUT_ACTION, conn);
474 return (InputStream) AccessController.doPrivileged(actions, m_acc);
475 }
476 catch (PrivilegedActionException ex)
477 {
478 if (ex.getException() instanceof IOException)
479 {
480 throw (IOException) ex.getException();
481 }
482 throw (RuntimeException) ex.getException();
483 }
484 }
485 else
486 {
487 return conn.getInputStream();
488 }
489 }
490
491 public boolean deleteFile(File target)
492 {
493 if (System.getSecurityManager() != null)
494 {
495 try
496 {
497 Actions actions = (Actions) m_actions.get();
498 actions.set(Actions.DELETE_FILE_ACTION, target);
499 return ((Boolean) AccessController.doPrivileged(actions, m_acc))
500 .booleanValue();
501 }
502 catch (PrivilegedActionException ex)
503 {
504 throw (RuntimeException) ex.getException();
505 }
506 }
507 else
508 {
509 return target.delete();
510 }
511 }
512
513 public File createTempFile(String prefix, String suffix, File dir)
514 throws IOException
515 {
516 if (System.getSecurityManager() != null)
517 {
518 try
519 {
520 Actions actions = (Actions) m_actions.get();
521 actions.set(Actions.CREATE_TMPFILE_ACTION, prefix, suffix, dir);
522 return (File) AccessController.doPrivileged(actions, m_acc);
523 }
524 catch (PrivilegedActionException ex)
525 {
526 if (ex.getException() instanceof IOException)
527 {
528 throw (IOException) ex.getException();
529 }
530 throw (RuntimeException) ex.getException();
531 }
532 }
533 else
534 {
535 return File.createTempFile(prefix, suffix, dir);
536 }
537 }
538
539 public URLConnection openURLConnection(URL url) throws IOException
540 {
541 if (System.getSecurityManager() != null)
542 {
543 try
544 {
545 Actions actions = (Actions) m_actions.get();
546 actions.set(Actions.OPEN_URLCONNECTION_ACTION, url);
547 return (URLConnection) AccessController.doPrivileged(actions,
548 m_acc);
549 }
550 catch (PrivilegedActionException ex)
551 {
552 if (ex.getException() instanceof IOException)
553 {
554 throw (IOException) ex.getException();
555 }
556 throw (RuntimeException) ex.getException();
557 }
558 }
559 else
560 {
561 return url.openConnection();
562 }
563 }
564
565 public JarFileX openJAR(File file) throws IOException
566 {
567 if (System.getSecurityManager() != null)
568 {
569 try
570 {
571 Actions actions = (Actions) m_actions.get();
572 actions.set(Actions.OPEN_JARX_ACTION, file);
573 return (JarFileX) AccessController.doPrivileged(actions, m_acc);
574 }
575 catch (PrivilegedActionException ex)
576 {
577 if (ex.getException() instanceof IOException)
578 {
579 throw (IOException) ex.getException();
580 }
581 throw (RuntimeException) ex.getException();
582 }
583 }
584 else
585 {
586 return new JarFileX(file);
587 }
588 }
589
590 public JarFileX openJAR(File file, boolean verify) throws IOException
591 {
592 if (System.getSecurityManager() != null)
593 {
594 try
595 {
596 Actions actions = (Actions) m_actions.get();
597 actions.set(Actions.OPEN_JARX_VERIFY_ACTION, file, (verify ? Boolean.TRUE : Boolean.FALSE));
598 return (JarFileX) AccessController.doPrivileged(actions, m_acc);
599 }
600 catch (PrivilegedActionException ex)
601 {
602 if (ex.getException() instanceof IOException)
603 {
604 throw (IOException) ex.getException();
605 }
606 throw (RuntimeException) ex.getException();
607 }
608 }
609 else
610 {
611 return new JarFileX(file, verify);
612 }
613 }
614 // TODO: REFACTOR - SecureAction fix needed.
615 /*
616 public ModuleClassLoader createModuleClassLoader(ModuleImpl impl)
617 {
618 return createModuleClassLoader(impl, null);
619 }
620
621 public ModuleClassLoader createModuleClassLoader(ModuleImpl impl,
622 ProtectionDomain protectionDomain)
623 {
624 if (System.getSecurityManager() != null)
625 {
626 try
627 {
628 Actions actions = (Actions) m_actions.get();
629 actions.set(Actions.CREATE_MODULECLASSLOADER_ACTION, impl, protectionDomain);
630 return (ModuleClassLoader) AccessController.doPrivileged(actions, m_acc);
631 }
632 catch (PrivilegedActionException ex)
633 {
634 throw (RuntimeException) ex.getException();
635 }
636 }
637 else
638 {
639 return new ModuleClassLoader(impl, protectionDomain);
640 }
641 }
642 */
643 public void startActivator(BundleActivator activator, BundleContext context)
644 throws Exception
645 {
646 if (System.getSecurityManager() != null)
647 {
648 try
649 {
650 Actions actions = (Actions) m_actions.get();
651 actions.set(Actions.START_ACTIVATOR_ACTION, activator, context);
652 AccessController.doPrivileged(actions, m_acc);
653 }
654 catch (PrivilegedActionException ex)
655 {
656 throw ex.getException();
657 }
658 }
659 else
660 {
661 activator.start(context);
662 }
663 }
664
665 public void stopActivator(BundleActivator activator, BundleContext context)
666 throws Exception
667 {
668 if (System.getSecurityManager() != null)
669 {
670 try
671 {
672 Actions actions = (Actions) m_actions.get();
673 actions.set(Actions.STOP_ACTIVATOR_ACTION, activator, context);
674 AccessController.doPrivileged(actions, m_acc);
675 }
676 catch (PrivilegedActionException ex)
677 {
678 throw ex.getException();
679 }
680 }
681 else
682 {
683 activator.stop(context);
684 }
685 }
686
687 public Policy getPolicy()
688 {
689 if (System.getSecurityManager() != null)
690 {
691 try
692 {
693 Actions actions = (Actions) m_actions.get();
694 actions.set(Actions.GET_POLICY_ACTION, null);
695 return (Policy) AccessController.doPrivileged(actions, m_acc);
696 }
697 catch (PrivilegedActionException ex)
698 {
699 throw (RuntimeException) ex.getException();
700 }
701 }
702 else
703 {
704 return Policy.getPolicy();
705 }
706 }
707
708 public void addURLToURLClassLoader(URL extension, ClassLoader loader) throws Exception
709 {
710 if (System.getSecurityManager() != null)
711 {
712 Actions actions = (Actions) m_actions.get();
713 actions.set(Actions.ADD_EXTENSION_URL, extension, loader);
714 try
715 {
716 AccessController.doPrivileged(actions, m_acc);
717 }
718 catch (PrivilegedActionException e)
719 {
720 throw e.getException();
721 }
722 }
723 else
724 {
725 Method addURL =
726 URLClassLoader.class.getDeclaredMethod("addURL",
727 new Class[] {URL.class});
728 addURL.setAccessible(true);
729 addURL.invoke(loader, new Object[]{extension});
730 }
731 }
732
733 public Constructor getConstructor(Class target, Class[] types) throws Exception
734 {
735 if (System.getSecurityManager() != null)
736 {
737 Actions actions = (Actions) m_actions.get();
738 actions.set(Actions.GET_CONSTRUCTOR_ACTION, target, types);
739 try
740 {
741 return (Constructor) AccessController.doPrivileged(actions, m_acc);
742 }
743 catch (PrivilegedActionException e)
744 {
745 throw e.getException();
746 }
747 }
748 else
749 {
750 return target.getConstructor(types);
751 }
752 }
753
754 public Constructor getDeclaredConstructor(Class target, Class[] types) throws Exception
755 {
756 if (System.getSecurityManager() != null)
757 {
758 Actions actions = (Actions) m_actions.get();
759 actions.set(Actions.GET_DECLARED_CONSTRUCTOR_ACTION, target, types);
760 try
761 {
762 return (Constructor) AccessController.doPrivileged(actions, m_acc);
763 }
764 catch (PrivilegedActionException e)
765 {
766 throw e.getException();
767 }
768 }
769 else
770 {
771 return target.getDeclaredConstructor(types);
772 }
773 }
774
775 public Method getMethod(Class target, String method, Class[] types) throws Exception
776 {
777 if (System.getSecurityManager() != null)
778 {
779 Actions actions = (Actions) m_actions.get();
780 actions.set(Actions.GET_METHOD_ACTION, target, method, types);
781 try
782 {
783 return (Method) AccessController.doPrivileged(actions, m_acc);
784 }
785 catch (PrivilegedActionException e)
786 {
787 throw e.getException();
788 }
789 }
790 else
791 {
792 return target.getMethod(method, types);
793 }
794 }
795
796 public Method getDeclaredMethod(Class target, String method, Class[] types) throws Exception
797 {
798 if (System.getSecurityManager() != null)
799 {
800 Actions actions = (Actions) m_actions.get();
801 actions.set(Actions.GET_DECLARED_METHOD_ACTION, target, method, types);
802 try
803 {
804 return (Method) AccessController.doPrivileged(actions, m_acc);
805 }
806 catch (PrivilegedActionException e)
807 {
808 throw e.getException();
809 }
810 }
811 else
812 {
813 return target.getDeclaredMethod(method, types);
814 }
815 }
816
817 public void setAccesssible(AccessibleObject ao)
818 {
819 if (System.getSecurityManager() != null)
820 {
821 Actions actions = (Actions) m_actions.get();
822 actions.set(Actions.SET_ACCESSIBLE_ACTION, ao);
823 try
824 {
825 AccessController.doPrivileged(actions, m_acc);
826 }
827 catch (PrivilegedActionException e)
828 {
829 throw (RuntimeException) e.getException();
830 }
831 }
832 else
833 {
834 ao.setAccessible(true);
835 }
836 }
837
838 public Object invoke(Method method, Object target, Object[] params) throws Exception
839 {
840 if (System.getSecurityManager() != null)
841 {
842 Actions actions = (Actions) m_actions.get();
843 actions.set(Actions.INVOKE_METHOD_ACTION, method, target, params);
844 try
845 {
846 return AccessController.doPrivileged(actions, m_acc);
847 }
848 catch (PrivilegedActionException e)
849 {
850 throw e.getException();
851 }
852 }
853 else
854 {
855 method.setAccessible(true);
856 return method.invoke(target, params);
857 }
858 }
859
860 public Object invokeDirect(Method method, Object target, Object[] params) throws Exception
861 {
862 if (System.getSecurityManager() != null)
863 {
864 Actions actions = (Actions) m_actions.get();
865 actions.set(Actions.INVOKE_DIRECTMETHOD_ACTION, method, target, params);
866 try
867 {
868 return AccessController.doPrivileged(actions, m_acc);
869 }
870 catch (PrivilegedActionException e)
871 {
872 throw e.getException();
873 }
874 }
875 else
876 {
877 return method.invoke(target, params);
878 }
879 }
880
881 public Object invoke(Constructor constructor, Object[] params) throws Exception
882 {
883 if (System.getSecurityManager() != null)
884 {
885 Actions actions = (Actions) m_actions.get();
886 actions.set(Actions.INVOKE_CONSTRUCTOR_ACTION, constructor, params);
887 try
888 {
889 return AccessController.doPrivileged(actions, m_acc);
890 }
891 catch (PrivilegedActionException e)
892 {
893 throw e.getException();
894 }
895 }
896 else
897 {
898 return constructor.newInstance(params);
899 }
900 }
901
902 public Object getDeclaredField(Class targetClass, String name, Object target)
903 throws Exception
904 {
905 if (System.getSecurityManager() != null)
906 {
907 Actions actions = (Actions) m_actions.get();
908 actions.set(Actions.GET_FIELD_ACTION, targetClass, name, target);
909 try
910 {
911 return AccessController.doPrivileged(actions, m_acc);
912 }
913 catch (PrivilegedActionException e)
914 {
915 throw e.getException();
916 }
917 }
918 else
919 {
920 Field field = targetClass.getDeclaredField(name);
921 field.setAccessible(true);
922
923 return field.get(target);
924 }
925 }
926
927 public Object swapStaticFieldIfNotClass(Class targetClazz,
928 Class targetType, Class condition, String lockName) throws Exception
929 {
930 if (System.getSecurityManager() != null)
931 {
932 Actions actions = (Actions) m_actions.get();
933 actions.set(Actions.SWAP_FIELD_ACTION, targetClazz, targetType,
934 condition, lockName);
935 try
936 {
937 return AccessController.doPrivileged(actions, m_acc);
938 }
939 catch (PrivilegedActionException e)
940 {
941 throw e.getException();
942 }
943 }
944 else
945 {
946 return _swapStaticFieldIfNotClass(targetClazz, targetType,
947 condition, lockName);
948 }
949 }
950
951 private static Object _swapStaticFieldIfNotClass(Class targetClazz,
952 Class targetType, Class condition, String lockName) throws Exception
953 {
954 Object lock = null;
955 if (lockName != null)
956 {
957 try
958 {
959 Field lockField =
960 targetClazz.getDeclaredField(lockName);
961 lockField.setAccessible(true);
962 lock = lockField.get(null);
963 }
964 catch (NoSuchFieldException ex)
965 {
966 }
967 }
968 if (lock == null)
969 {
970 lock = targetClazz;
971 }
972 synchronized (lock)
973 {
974 Field[] fields = targetClazz.getDeclaredFields();
975
976 Object result = null;
977 for (int i = 0; (i < fields.length) && (result == null); i++)
978 {
979 if (Modifier.isStatic(fields[i].getModifiers()) &&
980 (fields[i].getType() == targetType))
981 {
982 fields[i].setAccessible(true);
983
984 result = fields[i].get(null);
985
986 if (result != null)
987 {
988 if ((condition == null) ||
989 !result.getClass().getName().equals(condition.getName()))
990 {
991 fields[i].set(null, null);
992 }
993 }
994 }
995 }
996 if (result != null)
997 {
998 if ((condition == null) || !result.getClass().getName().equals(condition.getName()))
999 {
1000 // reset cache
1001 for (int i = 0; i < fields.length; i++)
1002 {
1003 if (Modifier.isStatic(fields[i].getModifiers()) &&
1004 (fields[i].getType() == Hashtable.class))
1005 {
1006 fields[i].setAccessible(true);
1007 Hashtable cache = (Hashtable) fields[i].get(null);
1008 if (cache != null)
1009 {
1010 cache.clear();
1011 }
1012 }
1013 }
1014 }
1015 return result;
1016 }
1017 }
1018 return null;
1019 }
1020
1021 public void flush(Class targetClazz, Object lock) throws Exception
1022 {
1023 if (System.getSecurityManager() != null)
1024 {
1025 Actions actions = (Actions) m_actions.get();
1026 actions.set(Actions.FLUSH_FIELD_ACTION, targetClazz, lock);
1027 try
1028 {
1029 AccessController.doPrivileged(actions, m_acc);
1030 }
1031 catch (PrivilegedActionException e)
1032 {
1033 throw e.getException();
1034 }
1035 }
1036 else
1037 {
1038 _flush(targetClazz, lock);
1039 }
1040 }
1041
1042 private static void _flush(Class targetClazz, Object lock) throws Exception
1043 {
1044 synchronized (lock)
1045 {
1046 Field[] fields = targetClazz.getDeclaredFields();
1047 // reset cache
1048 for (int i = 0; i < fields.length; i++)
1049 {
1050 if (Modifier.isStatic(fields[i].getModifiers()) &&
1051 ((fields[i].getType() == Hashtable.class) || (fields[i].getType() == HashMap.class)))
1052 {
1053 fields[i].setAccessible(true);
1054 if (fields[i].getType() == Hashtable.class)
1055 {
1056 Hashtable cache = (Hashtable) fields[i].get(null);
1057 if (cache != null)
1058 {
1059 cache.clear();
1060 }
1061 }
1062 else
1063 {
1064 HashMap cache = (HashMap) fields[i].get(null);
1065 if (cache != null)
1066 {
1067 cache.clear();
1068 }
1069 }
1070 }
1071 }
1072 }
1073 }
1074
1075 private static class Actions implements PrivilegedExceptionAction
1076 {
1077 public static final int INITIALIZE_CONTEXT = 0;
1078
1079 public static final int ADD_EXTENSION_URL = 1;
1080 public static final int CREATE_MODULECLASSLOADER_ACTION = 2;
1081 public static final int CREATE_TMPFILE_ACTION = 3;
1082 public static final int CREATE_URL_ACTION = 4;
1083 public static final int CREATE_URL_WITH_CONTEXT_ACTION = 5;
1084 public static final int DELETE_FILE_ACTION = 6;
1085 public static final int EXEC_ACTION = 7;
1086 public static final int FILE_EXISTS_ACTION = 8;
1087 public static final int FILE_IS_DIRECTORY_ACTION = 9;
1088 public static final int FOR_NAME_ACTION = 10;
1089 public static final int GET_ABSOLUTE_PATH_ACTION = 11;
1090 public static final int GET_CONSTRUCTOR_ACTION = 12;
1091 public static final int GET_DECLARED_CONSTRUCTOR_ACTION = 13;
1092 public static final int GET_DECLARED_METHOD_ACTION = 14;
1093 public static final int GET_FIELD_ACTION = 15;
1094 public static final int GET_FILE_INPUT_ACTION = 16;
1095 public static final int GET_FILE_OUTPUT_ACTION = 17;
1096 public static final int GET_METHOD_ACTION = 19;
1097 public static final int GET_POLICY_ACTION = 20;
1098 public static final int GET_PROPERTY_ACTION = 21;
1099 public static final int GET_PARENT_CLASS_LOADER_ACTION = 22;
1100 public static final int GET_SYSTEM_CLASS_LOADER_ACTION = 23;
1101 public static final int GET_URL_INPUT_ACTION = 24;
1102 public static final int INVOKE_CONSTRUCTOR_ACTION = 25;
1103 public static final int INVOKE_DIRECTMETHOD_ACTION = 26;
1104 public static final int INVOKE_METHOD_ACTION = 27;
1105 public static final int LIST_DIRECTORY_ACTION = 28;
1106 public static final int MAKE_DIRECTORIES_ACTION = 29;
1107 public static final int MAKE_DIRECTORY_ACTION = 30;
1108 public static final int OPEN_JARX_ACTION = 31;
1109 public static final int OPEN_JARX_VERIFY_ACTION = 32;
1110 public static final int OPEN_URLCONNECTION_ACTION = 33;
1111 public static final int RENAME_FILE_ACTION = 34;
1112 public static final int SET_ACCESSIBLE_ACTION = 35;
1113 public static final int START_ACTIVATOR_ACTION = 36;
1114 public static final int STOP_ACTIVATOR_ACTION = 37;
1115 public static final int SWAP_FIELD_ACTION = 38;
1116 public static final int SYSTEM_EXIT_ACTION = 39;
1117 public static final int FLUSH_FIELD_ACTION = 40;
1118 public static final int GET_CLASS_LOADER_ACTION = 41;
1119
1120 private int m_action = -1;
1121 private Object m_arg1 = null;
1122 private Object m_arg2 = null;
1123 private Object m_arg3 = null;
1124 private Object m_arg4 = null;
1125 private Object m_arg5 = null;
1126
1127 public void set(int action)
1128 {
1129 m_action = action;
1130 }
1131
1132 public void set(int action, Object arg1)
1133 {
1134 m_action = action;
1135 m_arg1 = arg1;
1136 }
1137
1138 public void set(int action, Object arg1, Object arg2)
1139 {
1140 m_action = action;
1141 m_arg1 = arg1;
1142 m_arg2 = arg2;
1143 }
1144
1145 public void set(int action, Object arg1, Object arg2, Object arg3)
1146 {
1147 m_action = action;
1148 m_arg1 = arg1;
1149 m_arg2 = arg2;
1150 m_arg3 = arg3;
1151 }
1152
1153 public void set(int action, Object arg1, Object arg2, Object arg3,
1154 Object arg4)
1155 {
1156 m_action = action;
1157 m_arg1 = arg1;
1158 m_arg2 = arg2;
1159 m_arg3 = arg3;
1160 m_arg4 = arg4;
1161 }
1162
1163 public void set(int action, Object arg1, Object arg2, Object arg3,
1164 Object arg4, Object arg5)
1165 {
1166 m_action = action;
1167 m_arg1 = arg1;
1168 m_arg2 = arg2;
1169 m_arg3 = arg3;
1170 m_arg4 = arg4;
1171 m_arg5 = arg5;
1172 }
1173
1174 private void unset()
1175 {
1176 m_action = -1;
1177 m_arg1 = null;
1178 m_arg2 = null;
1179 m_arg3 = null;
1180 m_arg4 = null;
1181 m_arg5 = null;
1182 }
1183
1184 public Object run() throws Exception
1185 {
1186 int action = m_action;
1187 Object arg1 = m_arg1;
1188 Object arg2 = m_arg2;
1189 Object arg3 = m_arg3;
1190 Object arg4 = m_arg4;
1191 Object arg5 = m_arg5;
1192
1193 unset();
1194
1195 if (action == INITIALIZE_CONTEXT)
1196 {
1197 return AccessController.getContext();
1198 }
1199 else if (action == GET_PROPERTY_ACTION)
1200 {
1201 return System.getProperty((String) arg1, (String) arg2);
1202 }
1203 else if (action == GET_PARENT_CLASS_LOADER_ACTION)
1204 {
1205 return ((ClassLoader) arg1).getParent();
1206 }
1207 else if (action == GET_SYSTEM_CLASS_LOADER_ACTION)
1208 {
1209 return ClassLoader.getSystemClassLoader();
1210 }
1211 else if (action == FOR_NAME_ACTION)
1212 {
1213 return Class.forName((String) arg1);
1214 }
1215 else if (action == CREATE_URL_ACTION)
1216 {
1217 return new URL((String) arg1, (String) arg2,
1218 ((Integer) arg3).intValue(), (String) arg4,
1219 (URLStreamHandler) arg5);
1220 }
1221 else if (action == CREATE_URL_WITH_CONTEXT_ACTION)
1222 {
1223 return new URL((URL) arg1, (String) arg2,
1224 (URLStreamHandler) arg3);
1225 }
1226 else if (action == EXEC_ACTION)
1227 {
1228 return Runtime.getRuntime().exec((String) arg1);
1229 }
1230 else if (action == GET_ABSOLUTE_PATH_ACTION)
1231 {
1232 return ((File) arg1).getAbsolutePath();
1233 }
1234 else if (action == FILE_EXISTS_ACTION)
1235 {
1236 return ((File) arg1).exists() ? Boolean.TRUE : Boolean.FALSE;
1237 }
1238 else if (action == FILE_IS_DIRECTORY_ACTION)
1239 {
1240 return ((File) arg1).isDirectory() ? Boolean.TRUE : Boolean.FALSE;
1241 }
1242 else if (action == MAKE_DIRECTORY_ACTION)
1243 {
1244 return ((File) arg1).mkdir() ? Boolean.TRUE : Boolean.FALSE;
1245 }
1246 else if (action == MAKE_DIRECTORIES_ACTION)
1247 {
1248 return ((File) arg1).mkdirs() ? Boolean.TRUE : Boolean.FALSE;
1249 }
1250 else if (action == LIST_DIRECTORY_ACTION)
1251 {
1252 return ((File) arg1).listFiles();
1253 }
1254 else if (action == RENAME_FILE_ACTION)
1255 {
1256 return ((File) arg1).renameTo((File) arg2) ? Boolean.TRUE : Boolean.FALSE;
1257 }
1258 else if (action == GET_FILE_INPUT_ACTION)
1259 {
1260 return new FileInputStream((File) arg1);
1261 }
1262 else if (action == GET_FILE_OUTPUT_ACTION)
1263 {
1264 return new FileOutputStream((File) arg1);
1265 }
1266 else if (action == DELETE_FILE_ACTION)
1267 {
1268 return ((File) arg1).delete() ? Boolean.TRUE : Boolean.FALSE;
1269 }
1270 else if (action == OPEN_JARX_ACTION)
1271 {
1272 return new JarFileX((File) arg1);
1273 }
1274 else if (action == OPEN_JARX_VERIFY_ACTION)
1275 {
1276 return new JarFileX((File) arg1, ((Boolean) arg2).booleanValue());
1277 }
1278 else if (action == GET_URL_INPUT_ACTION)
1279 {
1280 return ((URLConnection) arg1).getInputStream();
1281 }
1282 else if (action == START_ACTIVATOR_ACTION)
1283 {
1284 ((BundleActivator) arg1).start((BundleContext) arg2);
1285 return null;
1286 }
1287 else if (action == STOP_ACTIVATOR_ACTION)
1288 {
1289 ((BundleActivator) arg1).stop((BundleContext) arg2);
1290 return null;
1291 }
1292 else if (action == SYSTEM_EXIT_ACTION)
1293 {
1294 System.exit(((Integer) arg1).intValue());
1295 }
1296 else if (action == GET_POLICY_ACTION)
1297 {
1298 return Policy.getPolicy();
1299 }
1300 else if (action == CREATE_TMPFILE_ACTION)
1301 {
1302 return File.createTempFile((String) arg1, (String) arg2,
1303 (File) arg3);
1304 }
1305 else if (action == OPEN_URLCONNECTION_ACTION)
1306 {
1307 return ((URL) arg1).openConnection();
1308 }
1309 else if (action == ADD_EXTENSION_URL)
1310 {
1311 Method addURL =
1312 URLClassLoader.class.getDeclaredMethod("addURL",
1313 new Class[] {URL.class});
1314 addURL.setAccessible(true);
1315 addURL.invoke(arg2, new Object[]{arg1});
1316 }
1317 else if (action == GET_CONSTRUCTOR_ACTION)
1318 {
1319 return ((Class) arg1).getConstructor((Class[]) arg2);
1320 }
1321 else if (action == GET_DECLARED_CONSTRUCTOR_ACTION)
1322 {
1323 return ((Class) arg1).getDeclaredConstructor((Class[]) arg2);
1324 }
1325 else if (action == GET_METHOD_ACTION)
1326 {
1327 return ((Class) arg1).getMethod((String) arg2, (Class[]) arg3);
1328 }
1329 else if (action == INVOKE_METHOD_ACTION)
1330 {
1331 ((Method) arg1).setAccessible(true);
1332 return ((Method) arg1).invoke(arg2, (Object[]) arg3);
1333 }
1334 else if (action == INVOKE_DIRECTMETHOD_ACTION)
1335 {
1336 return ((Method) arg1).invoke(arg2, (Object[]) arg3);
1337 }
1338 else if (action == INVOKE_CONSTRUCTOR_ACTION)
1339 {
1340 return ((Constructor) arg1).newInstance((Object[]) arg2);
1341 }
1342 else if (action == SWAP_FIELD_ACTION)
1343 {
1344 return _swapStaticFieldIfNotClass((Class) arg1,
1345 (Class) arg2, (Class) arg3, (String) arg4);
1346 }
1347 else if (action == GET_FIELD_ACTION)
1348 {
1349 Field field = ((Class) arg1).getDeclaredField((String) arg2);
1350 field.setAccessible(true);
1351 return field.get(arg3);
1352 }
1353 else if (action == GET_DECLARED_METHOD_ACTION)
1354 {
1355 return ((Class) arg1).getDeclaredMethod((String) arg2, (Class[]) arg3);
1356 }
1357 else if (action == SET_ACCESSIBLE_ACTION)
1358 {
1359 ((AccessibleObject) arg1).setAccessible(true);
1360 }
1361 else if (action == FLUSH_FIELD_ACTION)
1362 {
1363 _flush(((Class) arg1), arg2);
1364 }
1365 else if (action == GET_CLASS_LOADER_ACTION)
1366 {
1367 return ((Class) arg1).getClassLoader();
1368 }
1369
1370 return null;
1371 }
1372 }
1373 }