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

com.arangodb.BaseArangoDriver Maven / Gradle / Ivy

There is a newer version: 7.15.0
Show newest version
/*
 * Copyright (C) 2012 tamtam180
 *
 * Licensed 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 com.arangodb;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import com.arangodb.entity.BaseEntity;
import com.arangodb.entity.DefaultEntity;
import com.arangodb.entity.DocumentEntity;
import com.arangodb.entity.EntityDeserializers;
import com.arangodb.entity.EntityFactory;
import com.arangodb.entity.KeyValueEntity;
import com.arangodb.entity.ReplicationDumpHeader;
import com.arangodb.entity.StreamEntity;
import com.arangodb.entity.marker.MissingInstanceCreater;
import com.arangodb.http.HttpResponseEntity;
import com.arangodb.util.DateUtils;
import com.arangodb.util.ReflectionUtils;
import com.arangodb.util.StringUtils;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

/**
 * @author tamtam180 - kirscheless at gmail.com
 *
 */
public abstract class BaseArangoDriver {

	private static final Pattern databaseNamePattern = Pattern.compile("^[a-zA-Z][a-zA-Z0-9\\-_]{0,63}$");

	// protected String createDocumentHandle(long collectionId, long documentId)
	// {
	// // validateCollectionNameは不要
	// return collectionId + "/" + documentId;
	// }
	//
	// protected String createDocumentHandle(String collectionName, long
	// documentId) throws ArangoException {
	// validateCollectionName(collectionName);
	// return collectionName + "/" + documentId;
	// }

	protected String createDocumentHandle(long collectionId, String documentKey) {
		return collectionId + "/" + documentKey;
	}

	protected String createDocumentHandle(String collectionName, String documentKey) throws ArangoException {
		validateCollectionName(collectionName);
		return collectionName + "/" + documentKey;
	}

	protected void validateCollectionName(String name) throws ArangoException {
		if (name.indexOf('/') != -1) {
			throw new ArangoException("does not allow '/' in name.");
		}
	}

	protected void validateDocumentHandle(String documentHandle) throws ArangoException {
		int pos = documentHandle.indexOf('/');
		if (pos > 0) {
			String collectionName = documentHandle.substring(0, pos);
			String documentKey = documentHandle.substring(pos + 1);

			validateCollectionName(collectionName);
			if (collectionName.length() != 0 && documentKey.length() != 0) {
				return;
			}
		}
		throw new ArangoException("invalid format documentHandle:" + documentHandle);
	}

	/**
	 * @param database
	 * @param allowNull
	 * @throws ArangoException
	 * @see DatabaseNames
	 *      documentation
	 */
	protected void validateDatabaseName(String database, boolean allowNull) throws ArangoException {
		boolean valid = false;
		if (database == null) {
			if (allowNull) {
				valid = true;
			}
		} else {
			valid = databaseNamePattern.matcher(database).matches();
			if (database.equals("_system")) {
				valid = true;
			}
		}
		if (!valid) {
			throw new ArangoException("invalid format database:" + database);
		}
	}

	protected void setKeyValueHeader(HttpResponseEntity res, KeyValueEntity entity) throws ArangoException {

		Map headers = res.getHeaders();

		try {
			String strCreated = headers.get("x-voc-created");
			if (strCreated != null) {
				entity.setCreated(DateUtils.parse(strCreated, "yyyy-MM-dd'T'HH:mm:ss'Z'"));
			}

			String strExpires = headers.get("x-voc-expires");
			if (strExpires != null) {
				entity.setExpires(DateUtils.parse(strExpires, "yyyy-MM-dd'T'HH:mm:ss'Z'"));
			}

			String strExtened = headers.get("x-voc-extended");
			if (strExtened != null) {
				Map attributes = EntityFactory.createEntity(strExtened, Map.class);
				entity.setAttributes(attributes);
			}

		} catch (ParseException e) {
			throw new ArangoException(e);
		}

	}

	protected ReplicationDumpHeader toReplicationDumpHeader(HttpResponseEntity res) {
		ReplicationDumpHeader header = new ReplicationDumpHeader();

		Map headerMap = res.getHeaders();
		String value;

		value = headerMap.get("x-arango-replication-active");
		if (value != null) {
			header.setActive(Boolean.parseBoolean(value));
		}

		value = headerMap.get("x-arango-replication-lastincluded");
		if (value != null) {
			header.setLastincluded(Long.parseLong(value));
		}

		value = headerMap.get("x-arango-replication-lasttick");
		if (value != null) {
			header.setLasttick(Long.parseLong(value));
		}

		value = headerMap.get("x-arango-replication-checkmore");
		if (value != null) {
			header.setCheckmore(Boolean.parseBoolean(value));
		}

		return header;
	}

	/**
	 * Creates an entity object
	 * 
	 * @param res
	 *            the response of the database
	 * @param clazz
	 *            the class of the entity object
	 * @param pclazz
	 *            the class of the object wrapped in the entity object
	 * @param validate
	 *            true for validation
	 * @return the result entity object of class T (T extends BaseEntity)
	 * @throws ArangoException
	 */
	protected  T createEntity(
		HttpResponseEntity res,
		Class clazz,
		Class[] pclazz,
		boolean validate) throws ArangoException {
		if (res == null) {
			return null;
		}
		boolean isDocumentEntity = false;
		boolean requestSuccessful = true;
		// the following was added to ensure, that attributes with a key like
		// "error", "code", "errorNum"
		// and "etag" will be serialized, when no error was thrown by the
		// database
		if (clazz == DocumentEntity.class) {
			isDocumentEntity = true;
		}
		int statusCode = res.getStatusCode();
		if (statusCode >= 400) {
			requestSuccessful = false;
			DefaultEntity defaultEntity = new DefaultEntity();
			if (res.getText() != null && !res.getText().equalsIgnoreCase("") && statusCode != 500) {
				JsonParser jsonParser = new JsonParser();
				JsonElement jsonElement = jsonParser.parse(res.getText());
				JsonObject jsonObject = jsonElement.getAsJsonObject();
				JsonElement errorMessage = jsonObject.get("errorMessage");
				defaultEntity.setErrorMessage(errorMessage.getAsString());
				JsonElement errorNumber = jsonObject.get("errorNum");
				defaultEntity.setErrorNumber(errorNumber.getAsInt());
			} else {
				String statusPhrase = "";
				switch (statusCode) {
				case 400:
					statusPhrase = "Bad Request";
					break;
				case 401:
					statusPhrase = "Unauthorized";
					break;
				case 403:
					statusPhrase = "Forbidden";
					break;
				case 404:
					statusPhrase = "Not Found";
					break;
				case 405:
					statusPhrase = "Method Not Allowed";
					break;
				case 406:
					statusPhrase = "Not Acceptable";
					break;
				case 407:
					statusPhrase = "Proxy Authentication Required";
					break;
				case 408:
					statusPhrase = "Request Time-out";
					break;
				case 409:
					statusPhrase = "Conflict";
					break;
				case 500:
					statusPhrase = "Internal Server Error";
					break;
				default:
					statusPhrase = "unknown error";
					break;
				}

				defaultEntity.setErrorMessage(statusPhrase);
				if (statusCode == 500) {
					defaultEntity.setErrorMessage(statusPhrase + ": " + res.getText());
				}
			}

			defaultEntity.setCode(statusCode);
			defaultEntity.setStatusCode(statusCode);
			defaultEntity.setError(true);
			ArangoException arangoException = new ArangoException(defaultEntity);
			arangoException.setCode(statusCode);
			throw arangoException;
		}

		try {
			EntityDeserializers.setParameterized(pclazz);

			T entity = createEntityImpl(res, clazz);
			if (entity == null) {
				Class c = MissingInstanceCreater.getMissingClass(clazz);
				entity = ReflectionUtils.newInstance(c);
			} else if (res.isBatchRepsonse()) {
				try {
					entity = clazz.newInstance();
				} catch (Exception e) {
					throw new ArangoException(e);
				}
			}
			setStatusCode(res, entity);
			if (validate) {
				validate(res, entity);
			}

			if (isDocumentEntity && requestSuccessful) {
				entity.setCode(statusCode);
				entity.setErrorMessage(null);
				entity.setError(false);
				entity.setErrorNumber(0);
			}

			return entity;
		} finally {
			EntityDeserializers.removeParameterized();
		}
	}

	protected  T createEntity(String str, Class clazz, Class... pclazz) throws ArangoException {
		try {
			EntityDeserializers.setParameterized(pclazz);
			return EntityFactory.createEntity(str, clazz);
		} finally {
			EntityDeserializers.removeParameterized();
		}
	}

	protected  T createEntity(HttpResponseEntity res, Class clazz) throws ArangoException {
		return createEntity(res, clazz, null, true);
	}

	protected  T createEntity(HttpResponseEntity res, Class clazz, Class... pclazz)
			throws ArangoException {
		return createEntity(res, clazz, pclazz, true);
	}

	protected void setStatusCode(HttpResponseEntity res, BaseEntity entity) throws ArangoException {
		if (entity != null) {
			if (res.getEtag() > 0) {
				entity.setEtag(res.getEtag());
			}
			entity.setStatusCode(res.getStatusCode());
			if (res.getRequestId() != null) {
				entity.setRequestId(res.getRequestId());
			}
		}
	}

	protected void validate(HttpResponseEntity res, BaseEntity entity) throws ArangoException {

		if (entity != null) {
			if (entity.isError()) {
				throw new ArangoException(entity);
			}
		}

		// Custom Error
		if (res.getStatusCode() >= 400) {

			if (res.isTextResponse()) {
				// entity.setErrorNumber(0);
				entity.setErrorNumber(res.getStatusCode());
				entity.setErrorMessage(res.getText());
			} else {
				entity.setErrorNumber(res.getStatusCode());
				entity.setErrorMessage(res.getStatusPhrase());
			}

			switch (res.getStatusCode()) {
			case 401:
				entity.setErrorMessage("Unauthorized");
				break;
			case 403:
				entity.setErrorMessage("Forbidden");
				break;
			default:
			}

			throw new ArangoException(entity);
		}
	}

	@SuppressWarnings("unchecked")
	protected  T createEntityImpl(HttpResponseEntity res, Class type) throws ArangoException {
		if (res.isJsonResponse()) {
			T entity = EntityFactory.createEntity(res.getText(), type);
			return entity;
		}
		if (res.isDumpResponse() && StreamEntity.class.isAssignableFrom(type)) {
			return (T) new StreamEntity(res.getStream());
		}
		return null;
		// throw new IllegalStateException("unknown response content-type:" +
		// res.getContentType());
	}

	protected String createEndpointUrl(String database, Object... paths) throws ArangoException {

		// FIXME: Very very foolish implement.

		List list = new ArrayList();

		if (database != null) {
			validateDatabaseName(database, false);
			list.add("_db");
			list.add(database);
		}
		for (Object path : paths) {
			if (path != null) {
				list.add(path.toString());
			}
		}
		return StringUtils.join(false, list);
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy