/** Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. Contact: SYSTAP, LLC DBA Blazegraph 2501 Calvert ST NW #106 Washington, DC 20008 licenses@blazegraph.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.bigdata.rdf.internal.impl.literal; import java.util.Arrays; import org.openrdf.model.Literal; import com.bigdata.btree.keys.KeyBuilder; import com.bigdata.rdf.internal.DTE; import com.bigdata.rdf.internal.DTEExtension; import com.bigdata.rdf.internal.IExtension; import com.bigdata.rdf.internal.IV; import com.bigdata.rdf.internal.InlineLiteralIV; import com.bigdata.rdf.internal.InlineURIHandler; import com.bigdata.rdf.internal.impl.uri.URIExtensionIV; import com.bigdata.rdf.lexicon.LexiconRelation; import com.bigdata.rdf.model.BigdataLiteral; import com.bigdata.util.BytesUtil; /** * An inline literal IV composed of an array of other inline literal IVs. This * IV is meant to be used with LiteralExtensionIV and URIExtensionIV as the * delegate for an inline literal extension or an inline URI. This IV is not * directly materializable into a Literal outside the context of a literal * extension factory or an inline URI handler. * <p> * Encoded as flags, DTE.ARRAY, array length, array. The array length is * encoded using a single byte, so the maximum array length is 256 elements * (empty arrays are not allowed). * * @see {@link LiteralExtensionIV} * @see {@link URIExtensionIV} * @see {@link InlineURIHandler} * @see {@link IExtension} * * @author mikepersonick */ public class LiteralArrayIV extends AbstractLiteralIV<BigdataLiteral, Object[]> { private static final long serialVersionUID = 9136542087440805253L; /** * The inline literal array. */ private final InlineLiteralIV<?,?>[] ivs; /** * Only used for compareTo() and byteLength(). Encoding takes place in * AbstractIV, decoding in IVUtility. */ private transient byte[] key; /** * Cached hash code. */ private transient int hashCode = 0; /** * Construct an instance using the supplied inline literal IVs. The array * must not be empty and must not be more than 256 elements (using one * byte to encode the array length). * * @param ivs * the inline literal IVs */ public LiteralArrayIV(final InlineLiteralIV<?,?>... ivs) { super(DTE.Extension); // only using one byte for the array length if (ivs == null || ivs.length == 0 || ivs.length > 256) { throw new IllegalArgumentException(); } this.ivs = ivs; } @Override public DTEExtension getDTEX() { return DTEExtension.ARRAY; } public InlineLiteralIV<?,?>[] getIVs() { return ivs; } private byte[] key() { if (key == null) { key = super.encode(KeyBuilder.newInstance()).getKey(); } return key; } @Override public int byteLength() { return key().length; } @Override public LiteralArrayIV clone(boolean clearCache) { return new LiteralArrayIV(this.ivs); } @Override public int _compareTo(IV o) { if (!(o instanceof LiteralArrayIV)) { throw new IllegalArgumentException(); } final LiteralArrayIV iv = (LiteralArrayIV) o; return BytesUtil.compareBytes(key(), iv.key()); } @Override public int hashCode() { if (hashCode == 0) { hashCode = Arrays.hashCode(ivs); } return hashCode; } @Override public boolean equals(final Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; LiteralArrayIV other = (LiteralArrayIV) obj; if (!Arrays.equals(ivs, other.ivs)) return false; return true; } /** * Implement {@link Literal#getLabel()} for logging. Superclass uses * inline value. */ @Override public String getLabel() { return "LiteralArrayIV["+ivs.length+"]"; } /** * We could theoretically get all the inline values from the inline IVs * and return them here. */ @Override public Object[] getInlineValue() throws UnsupportedOperationException { throw new UnsupportedOperationException(); } /** * This IV cannot be materialized on its own. It can only be used * within the context of a {@link URIExtensionIV} or * {@link LiteralExtensionIV} as the delegate in cases where the extension * mechanism needs an array of inline IVs to represent its URI or Literal * respectively. */ @Override public BigdataLiteral asValue(LexiconRelation lex) throws UnsupportedOperationException { throw new UnsupportedOperationException(); } }