blob: a008ba180ab61fb19e0406817608fcf0bfb3c3d7 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You 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.apache.geode.internal;
import org.apache.geode.internal.i18n.LocalizedStrings;
import java.util.*;
import java.lang.reflect.*;
import java.io.InvalidClassException;
/**
* This class defines general native utils.
*
*
*/
public class SmHelper {
static final boolean pureMode = PureJavaMode.isPure();
/* ================== Native Methods =========================== */
/**
* Returns the size in bytes of a C pointer in this shared library, returns 4 for a 32 bit shared
* library, and 8 for a 64 bit shared library
*/
public static int pointerSizeBytes() {
if (pureMode) {
throw new IllegalStateException(
LocalizedStrings.SmHelper_POINTERSIZEBYTES_UNAVAILABLE_IN_PURE_MODE.toLocalizedString());
} else {
return _pointerSizeBytes();
}
}
private static native int _pointerSizeBytes();
/* ================== System Administration =========================== */
/**
* Sleeps for the specified number of nanoseconds.
*/
private static native void _nanosleep(int nanos);
/**
* Sleeps for the specified number of nanoseconds.
*/
public static void nanosleep(long nanos) throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (nanos <= 0) {
return;
}
if (nanos >= 1000000) {
Thread.sleep(nanos / 1000000, (int) (nanos % 1000000));
} else {
if (pureMode) {
// fix for bug 35150
Thread.yield();
} else {
_nanosleep((int) nanos);
}
}
}
/**
* Returns the GemFire native code library's version string.
*/
public static String getNativeVersion() {
if (pureMode) {
return LocalizedStrings.SmHelper_NATIVE_CODE_UNAVAILABLE.toLocalizedString();
} else {
return _getNativeVersion();
}
}
private static native String _getNativeVersion();
public static String getSystemId() {
if (pureMode) {
return "pureJavaMode";
} else {
return _getSystemId();
}
}
private static native String _getSystemId();
/** Cache of class -> has zero-arg constructor */
private static Map zeroArgConstructorCache = new HashMap();
/** Cache of class -> has public zero-arg constructor */
private static Map publicConstructorCache = new HashMap();
/**
* Allocates a new JOM instance of <code>c</code> and invokes the zero-argument constructor of
* <code>initClass</code> on the new object to initialize it. This takes the place of the late,
* lamented <code>allocateNewObject</code> method of <code>java.io.ObjectInputStream</code> in JDK
* 1.3.
*
* @throws InvalidClassException If <code>c</code> or <code>initClass</code> represents a
* primitive class.
* @throws NoSuchMethodError If <code>initClass</code> doesn't have a zero-argument constructor
* @throws IllegalAccessException If the zero-argument constructor is not public (only for
* <code>Externalizable</code> classes in which <code>c.equals(initClass)</code>
*/
public static Object allocateJOMObject(Class c, Class initClass)
throws IllegalAccessException, InvalidClassException {
if (c.isPrimitive()) {
throw new InvalidClassException(LocalizedStrings.SmHelper_IS_PRIMITIVE.toLocalizedString(),
c.getName());
} else if (initClass.isPrimitive()) {
throw new InvalidClassException(LocalizedStrings.SmHelper_IS_PRIMITIVE.toLocalizedString(),
initClass.getName());
}
// boolean hasZeroArgInit;
if (!zeroArgConstructorCache.containsKey(initClass)) {
try {
// Constructor init =
initClass.getDeclaredConstructor(new Class[0]);
if (Modifier.isPublic(initClass.getModifiers())) {
publicConstructorCache.put(initClass, Boolean.TRUE);
} else {
publicConstructorCache.put(initClass, Boolean.FALSE);
}
} catch (NoSuchMethodException ex) {
zeroArgConstructorCache.put(initClass, Boolean.FALSE);
throw new NoSuchMethodError();
}
} else {
Boolean b = (Boolean) zeroArgConstructorCache.get(initClass);
if (!b.booleanValue()) {
throw new NoSuchMethodError();
}
}
// // Doesn't let us invoke the non-public constructors of inner
// // classes
// boolean isPublic =
// ((Boolean) publicConstructorCache.get(initClass)).booleanValue();
// if (c.equals(initClass) && !isPublic) {
// throw new IllegalAccessException();
// }
return _allocateJOMObject(c, initClass);
}
/**
* Natively allocates a new JOM instance of <code>c</code> and invokes the zero-argument
* constructor of <code>initClass</code> on the new object to initialize it. This takes the place
* of the late, lamented <code>allocateNewObject</code> method of
* <code>java.io.ObjectInputStream</code> in JDK 1.3.
*/
private static native Object _allocateJOMObject(Class c, Class initClass);
/**
* Uses native code to set the value of an object JOM field
*/
public static native void _setObjectField(Object o, Field field, Object newValue);
}