1 /* 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package com.apple.jobjc; 26 27 import java.lang.ref.WeakReference; 28 import java.lang.reflect.Constructor; 29 30 31 public class NSClass<T extends ID> extends ID { 32 public static class NSClassNotFoundException extends RuntimeException{ 33 public NSClassNotFoundException(String m){ super(m); } 34 public NSClassNotFoundException(String m, Throwable cause){ super(m, cause); } 35 } 36 37 static native long getNativeClassByName(String name); 38 static native long getSuperClassOfClass(long classPtr); 39 static native String getClassNameOfClass(long classPtr); 40 static native long getClass(long objPtr); 41 42 public NSClass(final long ptr, final JObjCRuntime runtime) { 43 super(ptr, runtime); 44 } 45 46 public NSClass(final String name, final JObjCRuntime runtime) { 47 this(getNativeClassByName(name), runtime); 48 if(ptr == 0) throw new NSClassNotFoundException("NSClass pointer is 0. Found no class named " + name); 49 } 50 51 protected NSClass(final JObjCRuntime runtime){ 52 super(0, runtime); 53 final String sn = getClass().getSimpleName(); 54 final String name = sn.substring(0, sn.lastIndexOf("Class")); 55 ptr = getNativeClassByName(name); 56 if(ptr == 0) throw new NSClassNotFoundException("NSClass pointer is 0. Found no class named " + name); 57 } 58 59 NSClass<? super T> getSuperClass() { 60 return new NSClass<T>(getSuperClassOfClass(ptr), runtime); 61 } 62 63 String getClassName() { return getClassNameOfClass(ptr); } 64 65 @Override protected NativeObjectLifecycleManager getNativeObjectLifecycleManager() { 66 return NativeObjectLifecycleManager.Nothing.INST; 67 } 68 69 @Override public boolean equals(Object o){ 70 return (o instanceof NSClass) && (this.ptr == ((NSClass) o).ptr); 71 } 72 73 // 74 75 static <T extends NSClass> T getObjCClassFor(final JObjCRuntime runtime, final long clsPtr){ 76 if (clsPtr == 0) return null; 77 78 final WeakReference cachedObj = objectCache.get().get(clsPtr); 79 if(cachedObj != null && cachedObj.get() != null) return (T) cachedObj.get(); 80 81 final T newObj = (T) createNewObjCClassFor(runtime, clsPtr); 82 objectCache.get().put(clsPtr, new WeakReference(newObj)); 83 return newObj; 84 } 85 86 static <T extends NSClass> T createNewObjCClassFor(final JObjCRuntime runtime, final long clsPtr) { 87 final Constructor<T> ctor = getNSClassConstructorForClassPtr(runtime, clsPtr); 88 return (T) createNewObjCObjectForConstructor(ctor, clsPtr, runtime); 89 } 90 91 @SuppressWarnings("unchecked") 92 static <T extends NSClass> Constructor<T> getNSClassConstructorForClassPtr(final JObjCRuntime runtime, final long clazzPtr){ 93 final Class<T> clazz = getNSClassForClassPtr(runtime, clazzPtr); 94 Constructor<T> ctor; 95 try { 96 ctor = clazz.getDeclaredConstructor(CTOR_ARGS); 97 } catch (SecurityException e) { 98 throw new RuntimeException(e); 99 } catch (NoSuchMethodException e) { 100 throw new RuntimeException(e); 101 } 102 ctor.setAccessible(true); 103 return ctor; 104 } 105 106 @SuppressWarnings("unchecked") 107 static <T extends ID> Class<T> getNSClassForClassPtr(final JObjCRuntime runtime, final long clazzPtr){ 108 final String className = NSClass.getClassNameOfClass(clazzPtr); 109 final Class<T> clazz = (Class<T>) runtime.getClassForNativeClassName(className + "Class"); 110 if(clazz == null){ 111 final long superClazzPtr = NSClass.getSuperClassOfClass(clazzPtr); 112 if(superClazzPtr != 0) 113 return getNSClassForClassPtr(runtime, superClazzPtr); 114 } 115 return clazz; 116 } 117 }