All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.labymedia.ultralight.javascript.JavascriptValue Maven / Gradle / Ivy

/*
 * Ultralight Java - Java wrapper for the Ultralight web engine
 * Copyright (C) 2020 - 2021 LabyMedia and contributors
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package com.labymedia.ultralight.javascript;

import com.labymedia.ultralight.annotation.NativeCall;
import com.labymedia.ultralight.annotation.NativeType;
import com.labymedia.ultralight.annotation.Unstable;
import com.labymedia.ultralight.ffi.ObjectWithHandle;

import java.util.Objects;

/**
 * A JavaScript value. The base type for all JavaScript values, and polymorphic functions on them.
 */
@NativeType("JSValueRef")
public class JavascriptValue implements ObjectWithHandle, JavascriptLockedObject {
    private final long handle;
    private final JavascriptContextLock lock;

    /**
     * Constructs a new {@link JavascriptValue} wrapping an existing value reference in a locked context.
     *
     * @param handle The native value reference
     * @param lock   The context the value exists in, or {@code null}, if the object is not locked
     */
    @NativeCall
    JavascriptValue(@NativeType("JSValueRef") long handle, JavascriptContextLock lock) {
        this.handle = handle;
        this.lock = lock;

        if (this.lock != null) {
            this.lock.addDependency(this);
        }
    }

    /**
     * Protects this value and creates a copy which survives outside of the lock.
     *
     * @return The protected value
     */
    public native JavascriptProtectedValue protect();

    /**
     * Retrieves the type of this value.
     *
     * @return The type of this value
     */
    public native JavascriptType getType();

    /**
     * Tests whether this value is of the {@link JavascriptType#UNDEFINED} type.
     *
     * @return {@code true} if this value is an undefined value, {@code false} otherwise
     */
    public native boolean isUndefined();

    /**
     * Tests whether this value is of the {@link JavascriptType#NULL} type.
     *
     * @return {@code true} if this value is a null value, {@code false} otherwise
     */
    public native boolean isNull();

    /**
     * Tests whether this value is of the {@link JavascriptType#BOOLEAN} type.
     *
     * @return {@code true} if this value is a boolean value, {@code false} otherwise
     */
    public native boolean isBoolean();

    /**
     * Tests whether this value is of the {@link JavascriptType#NUMBER} type.
     *
     * @return {@code true} if this value is a number value, {@code false} otherwise
     */
    public native boolean isNumber();

    /**
     * Tests whether this value is of the {@link JavascriptType#STRING} type.
     *
     * @return {@code true} if this value is a string value, {@code false} otherwise
     */
    public native boolean isString();

    /**
     * Tests whether this value is of the {@link JavascriptType#SYMBOL} type.
     *
     * @return {@code true} if this value is a symbol value, {@code false} otherwise
     */
    public native boolean isSymbol();

    /**
     * Tests whether this value is of the {@link JavascriptType#OBJECT} type.
     *
     * @return {@code true} if this value is an object value, {@code false} otherwise
     */
    public native boolean isObject();

    /**
     * Tests whether this value is an instance of the provided {@link JavascriptClass}.
     *
     * @param clazz The class to test for
     * @return {@code true} if this value is an instance of the class, {@code false} otherwise
     */
    public native boolean isOfClass(JavascriptClass clazz);

    /**
     * Tests whether this value is of the {@link JavascriptType#OBJECT} type and is an array.
     *
     * @return {@code true} if this value is an array value, {@code false} otherwise
     */
    public native boolean isArray();

    /**
     * Tests whether this value is of the {@link JavascriptType#OBJECT} type and is a date.
     *
     * @return {@code true} if this value is a date value, {@code false} otherwise
     */
    public native boolean isDate();

    /**
     * Retrieves the {@link JavascriptTypedArrayType} of this value.
     *
     * @return The typed array type of this value
     * @throws JavascriptException If retrieving the type throws an exception
     */
    public native JavascriptTypedArrayType getTypedArrayType();

    /**
     * Tests whether this {@link JavascriptValue} is equal to another one, works like the == operator in Javascript.
     * 

* Passing {@code null} as the other value will result in the value being equal, if this value is a {@link * JavascriptType#NULL} or {@link JavascriptType#UNDEFINED} value * * @param other The value to compare this value with * @return {@code true} if the value is equal to the other one, {@code false} otherwise * @throws JavascriptException If an exception occurs while checking if the values are equal */ public native boolean isEqual(JavascriptValue other); /** * Tests whether this {@link JavascriptValue} is strictly equal to another one, works like the === operator in * Javascript. *

* Passing {@code null} as the other value will result in the value being equal, if this value is a {@link * JavascriptType#NULL} value. * * @param other The value to compare this value with * @return {@code true} if the value is strictly equal to the other one, {@code false} otherwise */ public native boolean isStrictEqual(JavascriptValue other); /** * Special equals method for {@link JavascriptValue}s. This method only compares the handle, use the {@link * #isEqual(JavascriptValue)} or {@link #isStrictEqual(JavascriptValue)} methods to check for equality. *

* As per Java standard, this method does not make {@code null} equal with {@link JavascriptType#NULL} or {@link * JavascriptType#UNDEFINED}, for methods following the javascript semantics, use {@link #isEqual(JavascriptValue)} * or {@link #isStrictEqual(JavascriptValue)}. *

* This method is unstable! * * @param other The object to compare this value with * @return {@code true} if the other object is also a {@link JavascriptValue} and has the same handle, {@code false} * otherwise */ @Unstable("Comparison of Javascript objects is subject to change") public boolean equals(Object other) { if (!(other instanceof JavascriptValue)) { return false; } return ((JavascriptValue) other).handle == handle; } /** * Tests whether a {@link JavascriptValue} value is an object constructed by a given constructor, * as compared by the Javascript instanceof operator. * * @param constructor The constructor to test against * @return {@code true} if this value has been constructed using the given constructor * @throws JavascriptException If an error occurs while checking if this object has been constructed using * the given constructor */ public native boolean isInstanceOfConstructor(JavascriptObject constructor) throws JavascriptException; /** * Converts this {@link JavascriptValue} into a JSON string. * * @param indentation Amount of spaces to use for indentation, clamped to 10 * @return This value as a JSON string * @throws JavascriptException If the conversion to a JSON string fails */ public native String toJson(short indentation); /** * Converts this {@link JavascriptValue} to a boolean. * * @return The boolean representation of this value */ public native boolean toBoolean(); /** * Converts this {@link JavascriptValue} to a number. * * @return The double representation of this value * @throws JavascriptException If the conversion to a number fails */ public native double toNumber(); /** * Copies the string representation of this value. * * @return The string representation of this value * @throws JavascriptException If the conversion to a string fails */ public native String toStringCopy(); /** * Converts this value into an object. * * @return This value as an object * @throws JavascriptException If the conversion to an object fails */ public native JavascriptObject toObject() throws JavascriptException; @Override public String toString() { if (lock != null && lock.isLocked()) { try { return toStringCopy(); } catch (JavascriptException ignored) { return "JavascriptValue{handle = " + handle + ", lock = " + lock.getHandle() + "}"; } } else { return "JavascriptValue{handle = " + handle + ", lock = none}"; } } @Override public int hashCode() { return Objects.hashCode(handle); } @Override public long getHandle() { if (lock == null) { throw new IllegalStateException("This value has never been locked"); } if (!lock.isLocked()) { throw new IllegalStateException("JavascriptContext is not locked anymore"); } return handle; } @Override public long getContextHandle() { if (lock == null) { throw new IllegalStateException("This value has never been locked"); } if (!lock.isLocked()) { throw new IllegalStateException("JavascriptContext is not locked anymore"); } return lock.getContext().getHandle(); } @Override public long getLockHandle() { if (lock == null) { throw new IllegalStateException("This value has never been locked"); } if (!lock.isLocked()) { throw new IllegalStateException("JavascriptContext is not locked anymore"); } return lock.getHandle(); } /** * Releases the internal reference. */ @Override public native void contextUnlocking(); @Override public JavascriptContextLock getLock() { return lock; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy