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

org.apache.jackrabbit.oak.plugins.value.Conversions Maven / Gradle / Ivy

There is a newer version: 1.62.0
Show newest version
/*
 * 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.jackrabbit.oak.plugins.value;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.TimeZone;

import com.google.common.base.Charsets;
import com.google.common.io.ByteStreams;

import org.apache.jackrabbit.oak.api.Blob;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.memory.StringBasedBlob;
import org.apache.jackrabbit.util.ISO8601;

/**
 * Utility class defining the conversion that take place between {@link org.apache.jackrabbit.oak.api.PropertyState}s
 * of different types. All conversions defined in this class are compatible with the conversions specified
 * in JSR-283 $3.6.4. However, some conversion in this class might not be defined in JSR-283.
 * 

* Example: *

 *    double three = convert("3.0").toDouble();
 * 
*/ public final class Conversions { private static final TimeZone UTC = TimeZone.getTimeZone("GMT+00:00"); private Conversions() {} /** * A converter converts a value to its representation as a specific target type. Not all target * types might be supported for a given value in which case implementations throw an exception. * The default implementations of the various conversion methods all operate on the string * representation of the underlying value (i.e. call {@code Converter.toString()}. */ public abstract static class Converter { /** * Convert to string * @return string representation of the converted value */ public abstract String toString(); /** * Convert to binary. This default implementation returns an new instance * of {@link StringBasedBlob}. * @return binary representation of the converted value */ public Blob toBinary() { return new StringBasedBlob(toString()); } /** * Convert to long. This default implementation is based on {@code Long.parseLong(String)}. * @return long representation of the converted value * @throws NumberFormatException */ public long toLong() { return Long.parseLong(toString()); } /** * Convert to double. This default implementation is based on {@code Double.parseDouble(String)}. * @return double representation of the converted value * @throws NumberFormatException */ public double toDouble() { return Double.parseDouble(toString()); } /** * Convert to date. This default implementation is based on {@code ISO8601.parse(String)}. * @return date representation of the converted value * @throws IllegalArgumentException if the string cannot be parsed into a date */ public Calendar toCalendar() { Calendar date = ISO8601.parse(toString()); if (date == null) { throw new IllegalArgumentException("Not a date string: " + toString()); } return date; } /** * Convert to date. This default implementation delegates to {@link #toCalendar()} * and returns the {@code ISO8601.format(Calendar)} value of the calendar. * @return date representation of the converted value * @throws IllegalArgumentException if the string cannot be parsed into a date */ public String toDate() { return ISO8601.format(toCalendar()); } /** * Convert to boolean. This default implementation is based on {@code Boolean.parseBoolean(String)}. * @return boolean representation of the converted value */ public boolean toBoolean() { return Boolean.parseBoolean(toString()); } /** * Convert to decimal. This default implementation is based on {@code new BigDecimal(String)}. * @return decimal representation of the converted value * @throws NumberFormatException */ public BigDecimal toDecimal() { return new BigDecimal(toString()); } } /** * Create a converter for a string. * @param value The string to convert * @return A converter for {@code value} * @throws NumberFormatException */ public static Converter convert(final String value) { return new Converter() { @Override public String toString() { return value; } }; } /** * Create a converter for a binary. * For the conversion to {@code String} the binary in interpreted as UTF-8 encoded string. * @param value The binary to convert * @return A converter for {@code value} * @throws IllegalArgumentException if the binary is inaccessible */ public static Converter convert(final Blob value) { return new Converter() { @Override public String toString() { try { InputStream in = value.getNewStream(); try { return new String(ByteStreams.toByteArray(in), Charsets.UTF_8); } finally { in.close(); } } catch (IOException e) { throw new IllegalArgumentException(e); } } @Override public Blob toBinary() { return value; } }; } /** * Create a converter for a long. {@code String.valueOf(long)} is used for the conversion to {@code String}. * The conversions to {@code double} and {@code long} return the {@code value} itself. * The conversion to decimal uses {@code new BigDecimal.valueOf(long)}. * The conversion to date interprets the value as number of milliseconds since {@code 1970-01-01T00:00:00.000Z}. * @param value The long to convert * @return A converter for {@code value} */ public static Converter convert(final long value) { return new Converter() { @Override public String toString() { return String.valueOf(value); } @Override public long toLong() { return value; } @Override public double toDouble() { return value; } @Override public Calendar toCalendar() { Calendar date = Calendar.getInstance(UTC); date.setTimeInMillis(value); return date; } @Override public BigDecimal toDecimal() { return BigDecimal.valueOf(value); } }; } /** * Create a converter for a double. {@code String.valueOf(double)} is used for the conversion to {@code String}. * The conversions to {@code double} and {@code long} return the {@code value} itself where in the former case * the value is casted to {@code long}. * The conversion to decimal uses {@code BigDecimal.valueOf(double)}. * The conversion to date interprets {@code toLong()} as number of milliseconds since * {@code 1970-01-01T00:00:00.000Z}. * @param value The double to convert * @return A converter for {@code value} */ public static Converter convert(final double value) { return new Converter() { @Override public String toString() { return String.valueOf(value); } @Override public long toLong() { return (long) value; } @Override public double toDouble() { return value; } @Override public Calendar toCalendar() { Calendar date = Calendar.getInstance(TimeZone.getTimeZone("GMT+00:00")); date.setTimeInMillis(toLong()); return date; } @Override public BigDecimal toDecimal() { return BigDecimal.valueOf(value); } }; } /** * Create a converter for a date. {@code ISO8601.format(Calendar)} is used for the conversion to {@code String}. * The conversions to {@code double}, {@code long} and {@code BigDecimal} return the number of milliseconds * since {@code 1970-01-01T00:00:00.000Z}. * @param value The date to convert * @return A converter for {@code value} */ public static Converter convert(final String value, Type type) { if (type == Type.DECIMAL) { return convert(convert(value).toDecimal()); } else if (type == Type.DOUBLE) { return convert(convert(value).toDouble()); } else if (type == Type.LONG) { return convert(convert(value).toLong()); } else if (type != Type.DATE) { return convert(value); } else { return new Converter() { @Override public String toString() { return value; } @Override public Calendar toCalendar() { return ISO8601.parse(toString()); } @Override public long toLong() { return toCalendar().getTimeInMillis(); } @Override public double toDouble() { return toLong(); } @Override public BigDecimal toDecimal() { return new BigDecimal(toLong()); } }; } } /** * Create a converter for a boolean. {@code Boolean.toString(boolean)} is used for the conversion to {@code String}. * @param value The boolean to convert * @return A converter for {@code value} */ public static Converter convert(final boolean value) { return new Converter() { @Override public String toString() { return Boolean.toString(value); } @Override public boolean toBoolean() { return value; } }; } /** * Create a converter for a decimal. {@code BigDecimal.toString()} is used for the conversion to {@code String}. * {@code BigDecimal.longValue()} and {@code BigDecimal.doubleValue()} is used for the conversions to * {@code long} and {@code double}, respectively. * The conversion to date interprets {@code toLong()} as number of milliseconds since * {@code 1970-01-01T00:00:00.000Z}. * @param value The decimal to convert * @return A converter for {@code value} */ public static Converter convert(final BigDecimal value) { return new Converter() { @Override public String toString() { return value.toString(); } @Override public long toLong() { return value.longValue(); } @Override public double toDouble() { return value.doubleValue(); } @Override public Calendar toCalendar() { Calendar date = Calendar.getInstance(TimeZone.getTimeZone("GMT+00:00")); date.setTimeInMillis(toLong()); return date; } @Override public BigDecimal toDecimal() { return value; } }; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy