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.usergrid.persistence.cassandra; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.UUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.usergrid.persistence.ConnectedEntityRef; import org.apache.usergrid.persistence.ConnectionRef; import org.apache.usergrid.persistence.EntityRef; import org.apache.usergrid.persistence.SimpleEntityRef; import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang.StringUtils; import static org.apache.usergrid.persistence.SimpleEntityRef.ref; import static org.apache.usergrid.utils.ConversionUtils.ascii; import static org.apache.usergrid.utils.ConversionUtils.uuidToBytesNullOk; /** @author edanuff */ public class ConnectionRefImpl implements ConnectionRef { public static final int MAX_LINKS = 1; /** * */ public static final int ALL = 0; /** * */ public static final int BY_CONNECTION_TYPE = 1; /** * */ public static final int BY_ENTITY_TYPE = 2; /** * */ public static final int BY_CONNECTION_AND_ENTITY_TYPE = 3; /** * */ public static final String NULL_ENTITY_TYPE = "Null"; /** * */ public static final UUID NULL_ID = new UUID(0, 0); private static final Logger logger = LoggerFactory.getLogger(ConnectionRefImpl.class); public static final String CONNECTION_ENTITY_TYPE = "Connection"; public static final String CONNECTION_ENTITY_CONNECTION_TYPE = "connection"; private final EntityRef connectingEntity; private final List<ConnectedEntityRef> pairedConnections; private final ConnectedEntityRef connectedEntity; /** * */ public ConnectionRefImpl() { connectingEntity = SimpleEntityRef.ref(); pairedConnections = Collections.emptyList(); connectedEntity = new ConnectedEntityRefImpl(); } /** * @param connectingEntityType * @param connectingEntityId * @param connectionType * @param connectedEntityType * @param connectedEntityId */ public ConnectionRefImpl(String connectingEntityType, UUID connectingEntityId, String connectionType, String connectedEntityType, UUID connectedEntityId) { connectingEntity = ref(connectingEntityType, connectingEntityId); pairedConnections = Collections.emptyList(); connectedEntity = new ConnectedEntityRefImpl(connectionType, connectedEntityType, connectedEntityId); } /** Create a connection from the source to the target entity */ public ConnectionRefImpl(EntityRef source, String connectionType, EntityRef target) { this.connectingEntity = ref(source); pairedConnections = Collections.emptyList(); this.connectedEntity = new ConnectedEntityRefImpl(connectionType, target); } public ConnectionRefImpl(ConnectionRef connection) { connectingEntity = connection.getConnectingEntity(); List<ConnectedEntityRef> pc = connection.getPairedConnections(); if (pc == null) { pc = Collections.emptyList(); } pairedConnections = pc; connectedEntity = connection.getConnectedEntity(); } public ConnectionRefImpl(EntityRef connectingEntity, ConnectedEntityRef... connections) { this.connectingEntity = ref(connectingEntity); ConnectedEntityRef ce = new ConnectedEntityRefImpl(); List<ConnectedEntityRef> pc = Collections.emptyList(); if (connections.length > 0) { ce = connections[connections.length - 1]; if (connections.length > 1) { pc = Arrays.asList(Arrays.copyOfRange(connections, 0, connections.length - 2)); } } pairedConnections = pc; connectedEntity = ce; } public ConnectionRefImpl(ConnectionRef connection, ConnectedEntityRef... connections) { if (connection == null) { throw new NullPointerException("ConnectionImpl constructor \'connection\' cannot be null"); } connectingEntity = connection.getConnectingEntity(); if (connections.length > 0) { pairedConnections = new ArrayList<ConnectedEntityRef>(); pairedConnections.addAll(connection.getPairedConnections()); pairedConnections.add(connection.getConnectedEntity()); connectedEntity = connections[connections.length - 1]; if (connections.length > 1) { pairedConnections.addAll(Arrays.asList(Arrays.copyOfRange(connections, 0, connections.length - 2))); } } else { pairedConnections = new ArrayList<ConnectedEntityRef>(); connectedEntity = new ConnectedEntityRefImpl(); } } public ConnectionRefImpl(EntityRef connectingEntity, List<ConnectedEntityRef> pairedConnections, ConnectedEntityRef connectedEntity) { this.connectingEntity = connectingEntity; this.pairedConnections = pairedConnections; this.connectedEntity = connectedEntity; } public UUID getSearchIndexId() { return null; } public String getSearchConnectionType() { return null; } public String getSearchResultType() { return null; } public String getSearchIndexName() { return null; } @Override public EntityRef getConnectingEntity() { return connectingEntity; } /** * @return */ public String getConnectingEntityType() { if (connectingEntity == null) { return null; } return connectingEntity.getType(); } /** * @return */ public UUID getConnectingEntityId() { if (connectingEntity == null) { return null; } return connectingEntity.getUuid(); } @Override public List<ConnectedEntityRef> getPairedConnections() { return pairedConnections; } public ConnectedEntityRef getFirstPairedConnection() { ConnectedEntityRef pairedConnection = null; if ((pairedConnections != null) && (pairedConnections.size() > 0)) { pairedConnection = pairedConnections.get(0); } return pairedConnection; } public UUID getFirstPairedConnectedEntityId() { ConnectedEntityRef pairedConnection = getFirstPairedConnection(); if (pairedConnection != null) { return pairedConnection.getUuid(); } return null; } public String getFirstPairedConnectedEntityType() { ConnectedEntityRef pairedConnection = getFirstPairedConnection(); if (pairedConnection != null) { return pairedConnection.getType(); } return null; } public String getFirstPairedConnectionType() { ConnectedEntityRef pairedConnection = getFirstPairedConnection(); if (pairedConnection != null) { return pairedConnection.getConnectionType(); } return null; } @Override public ConnectedEntityRef getConnectedEntity() { return connectedEntity; } /** * @return */ @Override public String getConnectionType() { if (connectedEntity == null) { return null; } return connectedEntity.getConnectionType(); } /** * @return */ public String getConnectedEntityType() { if (connectedEntity == null) { return null; } return connectedEntity.getType(); } /** * @return */ public UUID getConnectedEntityId() { return connectedEntity.getUuid(); } private UUID id; /** @return connection id */ @Override public UUID getUuid() { if (id == null) { List<ConnectedEntityRef> var = getPairedConnections(); id = getId(getConnectingEntity(), getConnectedEntity(), var.toArray(new ConnectedEntityRef[var.size()])); } return id; } @Override public String getType() { return CONNECTION_ENTITY_TYPE; } public UUID getIndexId() { return getIndexId(getConnectingEntity(), getConnectionType(), getConnectedEntityType(), pairedConnections.toArray(new ConnectedEntityRef[pairedConnections.size()])); } public UUID getConnectingIndexId() { return getIndexId(getConnectingEntity(), getConnectionType(), null, pairedConnections.toArray(new ConnectedEntityRef[pairedConnections.size()])); } public ConnectionRefImpl getConnectionToConnectionEntity() { return new ConnectionRefImpl(getConnectingEntity(), new ConnectedEntityRefImpl(CONNECTION_ENTITY_CONNECTION_TYPE, CONNECTION_ENTITY_TYPE, getUuid())); } /** @return index ids */ public UUID[] getIndexIds() { List<ConnectedEntityRef> var = getPairedConnections(); return getIndexIds(getConnectingEntity(), getConnectedEntity().getConnectionType(), getConnectedEntity().getType(), var.toArray(new ConnectedEntityRef[var.size()])); } static String typeOrDefault(String type) { if ((type == null) || (type.length() == 0)) { return NULL_ENTITY_TYPE; } return type; } static UUID idOrDefault(UUID uuid) { if (uuid == null) { return NULL_ID; } return uuid; } public static boolean connectionsNull(ConnectedEntityRef... pairedConnections) { if ((pairedConnections == null) || (pairedConnections.length == 0)) { return true; } for (ConnectedEntityRef pairedConnection : pairedConnections) { if (pairedConnection == null || pairedConnection.getUuid() == null || pairedConnection.getUuid().equals(NULL_ID)) { return true; } } return false; } public static ConnectedEntityRef[] getConnections(ConnectedEntityRef... connections) { return connections; } public static List<ConnectedEntityRef> getConnectionsList(ConnectedEntityRef... connections) { return Arrays.asList(connections); } /** @return connection id */ public static UUID getId(UUID connectingEntityId, String connectionType, UUID connectedEntityId) { return getId(connectingEntityId, null, null, connectionType, connectedEntityId); } /** * Connection id is constructed from packed structure of properties strings are truncated to 16 ascii bytes. * Connection id is now MD5'd into a UUID via UUID.nameUUIDFromBytes() so, technically string concatenation could be * used prior to MD5 * * @return connection id */ public static UUID getId(UUID connectingEntityId, String pairedConnectionType, UUID pairedConnectingEntityId, String connectionType, UUID connectedEntityId) { EntityRef connectingEntity = ref(connectingEntityId); ConnectedEntityRef[] pairedConnections = getConnections( new ConnectedEntityRefImpl(pairedConnectionType, null, pairedConnectingEntityId)); ConnectedEntityRef connectedEntity = new ConnectedEntityRefImpl(connectionType, null, connectedEntityId); return getId(connectingEntity, connectedEntity, pairedConnections); } public static UUID getId(EntityRef connectingEntity, ConnectedEntityRef connectedEntity, ConnectedEntityRef... pairedConnections) { UUID uuid = null; try { if (connectionsNull(pairedConnections) && connectionsNull(connectedEntity)) { return connectingEntity.getUuid(); } ByteArrayOutputStream byteStream = new ByteArrayOutputStream(16 + (32 * pairedConnections.length)); byteStream.write(uuidToBytesNullOk(connectingEntity.getUuid())); for (ConnectedEntityRef connection : pairedConnections) { String connectionType = connection.getConnectionType(); UUID connectedEntityID = connection.getUuid(); byteStream.write(ascii(StringUtils.lowerCase(connectionType))); byteStream.write(uuidToBytesNullOk(connectedEntityID)); } String connectionType = connectedEntity.getConnectionType(); if (connectionType == null) { connectionType = NULL_ENTITY_TYPE; } UUID connectedEntityID = connectedEntity.getUuid(); byteStream.write(ascii(StringUtils.lowerCase(connectionType))); byteStream.write(uuidToBytesNullOk(connectedEntityID)); byte[] raw_id = byteStream.toByteArray(); // logger.info("raw connection index id: " + // Hex.encodeHexString(raw_id)); uuid = UUID.nameUUIDFromBytes(raw_id); // logger.info("connection index uuid: " + uuid); } catch (IOException e) { logger.error("Unable to create connection UUID", e); } return uuid; } /** @return connection index id */ public static UUID getIndexId(UUID connectingEntityId, String connectionType, String connectedEntityType) { return getIndexId(connectingEntityId, null, null, connectionType, connectedEntityType); } /** @return connection index id */ public static UUID getIndexId(UUID connectingEntityId, String pairedConnectionType, UUID pairedConnectingEntityId, String connectionType, String connectedEntityType) { EntityRef connectingEntity = ref(connectingEntityId); ConnectedEntityRef[] pairedConnections = getConnections( new ConnectedEntityRefImpl(pairedConnectionType, null, pairedConnectingEntityId)); return getIndexId(connectingEntity, connectionType, connectedEntityType, pairedConnections); } public static UUID getIndexId(EntityRef connectingEntity, String connectionType, String connectedEntityType, ConnectedEntityRef... pairedConnections) { UUID uuid = null; try { if (connectionsNull(pairedConnections) && ((connectionType == null) && (connectedEntityType == null))) { return connectingEntity.getUuid(); } ByteArrayOutputStream byteStream = new ByteArrayOutputStream(16 + (32 * pairedConnections.length)); byteStream.write(uuidToBytesNullOk(connectingEntity.getUuid())); for (ConnectedEntityRef connection : pairedConnections) { String type = connection.getConnectionType(); UUID id = connection.getUuid(); byteStream.write(ascii(StringUtils.lowerCase(type))); byteStream.write(uuidToBytesNullOk(id)); } if (connectionType == null) { connectionType = NULL_ENTITY_TYPE; } if (connectedEntityType == null) { connectedEntityType = NULL_ENTITY_TYPE; } byteStream.write(ascii(StringUtils.lowerCase(connectionType))); byteStream.write(ascii(StringUtils.lowerCase(connectedEntityType))); byte[] raw_id = byteStream.toByteArray(); logger.info("raw connection index id: " + Hex.encodeHexString(raw_id)); uuid = UUID.nameUUIDFromBytes(raw_id); logger.info("connection index uuid: " + uuid); } catch (IOException e) { logger.error("Unable to create connection index UUID", e); } return uuid; } /** @return connection index id */ public static UUID getIndexId(int variant, UUID connectingEntityId, String pairedConnectionType, UUID pairedConnectingEntityId, String connectionType, String connectedEntityType) { EntityRef connectingEntity = ref(connectingEntityId); ConnectedEntityRef[] pairedConnections = getConnections( new ConnectedEntityRefImpl(pairedConnectionType, null, pairedConnectingEntityId)); return getIndexId(variant, connectingEntity, connectionType, connectedEntityType, pairedConnections); } public static UUID getIndexId(int variant, EntityRef connectingEntity, String connectionType, String connectedEntityType, ConnectedEntityRef... pairedConnections) { switch (variant) { case ALL: if (connectionsNull(pairedConnections)) { return connectingEntity.getUuid(); } else { return getIndexId(connectingEntity, null, null, pairedConnections); } case BY_ENTITY_TYPE: return getIndexId(connectingEntity, null, connectedEntityType, pairedConnections); case BY_CONNECTION_TYPE: return getIndexId(connectingEntity, connectionType, null, pairedConnections); case BY_CONNECTION_AND_ENTITY_TYPE: return getIndexId(connectingEntity, connectionType, connectedEntityType, pairedConnections); } return connectingEntity.getUuid(); } /** @return index ids */ public static UUID[] getIndexIds(UUID connectingEntityId, String connectionType, String connectedEntityType) { return getIndexIds(connectingEntityId, null, null, connectionType, connectedEntityType); } /** @return index ids */ public static UUID[] getIndexIds(UUID connectingEntityId, String pairedConnectionType, UUID pairedConnectingEntityId, String connectionType, String connectedEntityType) { UUID[] variants = new UUID[4]; for (int i = 0; i < 4; i++) { variants[i] = getIndexId(i, connectingEntityId, pairedConnectionType, pairedConnectingEntityId, connectionType, connectedEntityType); } return variants; } public static UUID[] getIndexIds(EntityRef connectingEntity, String connectionType, String connectedEntityType, ConnectedEntityRef... pairedConnections) { UUID[] variants = new UUID[4]; for (int i = 0; i < 4; i++) { variants[i] = getIndexId(i, connectingEntity, connectionType, connectedEntityType, pairedConnections); } return variants; } }