Java tutorial
/* * 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.hadoop.registry.client.binding; import com.fasterxml.jackson.core.JsonProcessingException; import org.apache.commons.lang3.StringUtils; import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.registry.client.exceptions.InvalidRecordException; import org.apache.hadoop.registry.client.exceptions.NoRecordException; import org.apache.hadoop.util.JsonSerialization; import java.io.EOFException; import java.io.IOException; /** * Support for marshalling objects to and from JSON. * <p> * This extends {@link JsonSerialization} with the notion * of a marker field in the JSON file, with * <ol> * <li>a fail-fast check for it before even trying to parse.</li> * <li>Specific IOException subclasses for a failure.</li> * </ol> * The rationale for this is not only to support different things in the, * registry, but the fact that all ZK nodes have a size > 0 when examined. * * @param <T> Type to marshal. */ @InterfaceAudience.Private @InterfaceStability.Evolving public class JsonSerDeser<T> extends JsonSerialization<T> { private static final String UTF_8 = "UTF-8"; public static final String E_NO_DATA = "No data at path"; public static final String E_DATA_TOO_SHORT = "Data at path too short"; public static final String E_MISSING_MARKER_STRING = "Missing marker string: "; /** * Create an instance bound to a specific type * @param classType class to marshall */ public JsonSerDeser(Class<T> classType) { super(classType, false, false); } /** * Deserialize from a byte array * @param path path the data came from * @param bytes byte array * @throws IOException all problems * @throws EOFException not enough data * @throws InvalidRecordException if the parsing failed -the record is invalid * @throws NoRecordException if the data is not considered a record: either * it is too short or it did not contain the marker string. */ public T fromBytes(String path, byte[] bytes) throws IOException { return fromBytes(path, bytes, ""); } /** * Deserialize from a byte array, optionally checking for a marker string. * <p> * If the marker parameter is supplied (and not empty), then its presence * will be verified before the JSON parsing takes place; it is a fast-fail * check. If not found, an {@link InvalidRecordException} exception will be * raised * @param path path the data came from * @param bytes byte array * @param marker an optional string which, if set, MUST be present in the * UTF-8 parsed payload. * @return The parsed record * @throws IOException all problems * @throws EOFException not enough data * @throws InvalidRecordException if the JSON parsing failed. * @throws NoRecordException if the data is not considered a record: either * it is too short or it did not contain the marker string. */ public T fromBytes(String path, byte[] bytes, String marker) throws IOException { int len = bytes.length; if (len == 0) { throw new NoRecordException(path, E_NO_DATA); } if (StringUtils.isNotEmpty(marker) && len < marker.length()) { throw new NoRecordException(path, E_DATA_TOO_SHORT); } String json = new String(bytes, 0, len, UTF_8); if (StringUtils.isNotEmpty(marker) && !json.contains(marker)) { throw new NoRecordException(path, E_MISSING_MARKER_STRING + marker); } try { return fromJson(json); } catch (JsonProcessingException e) { throw new InvalidRecordException(path, e.toString(), e); } } }