http://git-wip-us.apache.org/repos/asf/usergrid-java/blob/88039bad/src/main/java/org/apache/usergrid/java/client/UsergridRequest.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/usergrid/java/client/UsergridRequest.java b/src/main/java/org/apache/usergrid/java/client/UsergridRequest.java new file mode 100644 index 0000000..b16783e --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/UsergridRequest.java @@ -0,0 +1,205 @@ +/* + * 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.java.client; + +import okhttp3.HttpUrl; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; +import org.apache.usergrid.java.client.UsergridEnums.UsergridHttpMethod; +import org.apache.usergrid.java.client.auth.UsergridAuth; +import org.apache.usergrid.java.client.query.UsergridQuery; +import org.apache.usergrid.java.client.utils.JsonUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +@SuppressWarnings("unused") +public class UsergridRequest { + @NotNull public static final MediaType APPLICATION_JSON_MEDIA_TYPE = MediaType.parse("application/json; charset=utf-8"); + + @NotNull private UsergridHttpMethod method; + @NotNull private String baseUrl; + @NotNull private MediaType contentType; + + @Nullable private UsergridQuery query; + @Nullable private Map<String, Object> headers; + @Nullable private Map<String, Object> parameters; + @Nullable private Object data; + @Nullable private UsergridAuth auth; + @Nullable private String[] pathSegments; + + @NotNull + public UsergridHttpMethod getMethod() { return method; } + public void setMethod(@NotNull final UsergridHttpMethod method) { this.method = method; } + + @NotNull + public String getBaseUrl() { return baseUrl; } + public void setBaseUrl(@NotNull final String baseUrl) { this.baseUrl = baseUrl; } + + @NotNull + public MediaType getContentType() { return contentType; } + public void setContentType(@NotNull final MediaType contentType) { this.contentType = contentType; } + + @Nullable + public UsergridQuery getQuery() { return query; } + public void setQuery(@Nullable final UsergridQuery query) { this.query = query; } + + @Nullable + public Map<String,Object> getHeaders() { return headers; } + public void setHeaders(@Nullable final Map<String,Object> headers) { this.headers = headers; } + + @Nullable + public Map<String,Object> getParameters() { return parameters; } + public void setParameters(@Nullable final Map<String,Object> parameters) { this.parameters = parameters; } + + @Nullable + public Object getData() { return data; } + public void setData(@Nullable final Object data) { this.data = data; } + + @Nullable + public UsergridAuth getAuth() { return auth; } + public void setAuth(@Nullable final UsergridAuth auth) { this.auth = auth; } + + @Nullable + public String[] getPathSegments() { return pathSegments; } + public void setPathSegments(@Nullable final String[] pathSegments) { this.pathSegments = pathSegments; } + + private UsergridRequest() {} + + public UsergridRequest(@NotNull final UsergridHttpMethod method, + @NotNull final MediaType contentType, + @NotNull final String url, + @Nullable final UsergridQuery query, + @Nullable final UsergridAuth auth, + @Nullable final String... pathSegments) { + this.method = method; + this.contentType = contentType; + this.baseUrl = url; + this.query = query; + this.auth = auth; + this.pathSegments = pathSegments; + } + + public UsergridRequest(@NotNull final UsergridHttpMethod method, + @NotNull final MediaType contentType, + @NotNull final String url, + @Nullable final UsergridAuth auth, + @Nullable final String... pathSegments) { + this.method = method; + this.contentType = contentType; + this.baseUrl = url; + this.auth = auth; + this.pathSegments = pathSegments; + } + + public UsergridRequest(@NotNull final UsergridHttpMethod method, + @NotNull final MediaType contentType, + @NotNull final String url, + @Nullable final Map<String, Object> params, + @Nullable final Object data, + @Nullable final UsergridAuth auth, + @Nullable final String... pathSegments) { + this.method = method; + this.contentType = contentType; + this.baseUrl = url; + this.parameters = params; + this.data = data; + this.headers = null; + this.query = null; + this.auth = auth; + this.pathSegments = pathSegments; + } + + public UsergridRequest(@NotNull final UsergridHttpMethod method, + @NotNull final MediaType contentType, + @NotNull final String url, + @Nullable final Map<String, Object> params, + @Nullable final Object data, + @Nullable final Map<String, Object> headers, + @Nullable final UsergridQuery query, + @Nullable final UsergridAuth auth, + @Nullable final String... pathSegments) { + this.method = method; + this.contentType = contentType; + this.baseUrl = url; + this.parameters = params; + this.data = data; + this.headers = headers; + this.query = query; + this.auth = auth; + this.pathSegments = pathSegments; + } + + @NotNull + public Request buildRequest() { + Request.Builder requestBuilder = new Request.Builder(); + requestBuilder.url(this.constructUrl()); + this.addHeaders(requestBuilder); + requestBuilder.method(this.method.toString(),this.constructRequestBody()); + return requestBuilder.build(); + } + + @NotNull + protected HttpUrl constructUrl() { + String url = this.baseUrl; + if( this.query != null ) { + url += this.query.build(false); + } + HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder(); + if( this.pathSegments != null ) { + for( String path : this.pathSegments ) { + urlBuilder.addPathSegments(path); + } + } + if( this.parameters != null ) { + for (Map.Entry<String, Object> param : this.parameters.entrySet()) { + urlBuilder.addQueryParameter(param.getKey(),param.getValue().toString()); + } + } + return urlBuilder.build(); + } + + protected void addHeaders(@NotNull final Request.Builder requestBuilder) { + requestBuilder.addHeader("User-Agent", UsergridRequestManager.USERGRID_USER_AGENT); + if (this.auth != null ) { + String accessToken = this.auth.getAccessToken(); + if( accessToken != null ) { + requestBuilder.addHeader("Authorization", "Bearer " + accessToken); + } + } + if( this.headers != null ) { + for( Map.Entry<String,Object> header : this.headers.entrySet() ) { + requestBuilder.addHeader(header.getKey(),header.getValue().toString()); + } + } + } + + @Nullable + protected RequestBody constructRequestBody() { + RequestBody requestBody = null; + if (method == UsergridHttpMethod.POST || method == UsergridHttpMethod.PUT) { + String jsonString = ""; + if( this.data != null ) { + jsonString = JsonUtils.toJsonString(this.data); + } + requestBody = RequestBody.create(this.contentType,jsonString); + } + return requestBody; + } +}
http://git-wip-us.apache.org/repos/asf/usergrid-java/blob/88039bad/src/main/java/org/apache/usergrid/java/client/UsergridRequestManager.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/usergrid/java/client/UsergridRequestManager.java b/src/main/java/org/apache/usergrid/java/client/UsergridRequestManager.java new file mode 100644 index 0000000..7099d42 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/UsergridRequestManager.java @@ -0,0 +1,97 @@ +/* + * 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.java.client; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.apache.usergrid.java.client.UsergridEnums.UsergridHttpMethod; +import org.apache.usergrid.java.client.auth.UsergridAppAuth; +import org.apache.usergrid.java.client.auth.UsergridAuth; +import org.apache.usergrid.java.client.model.UsergridUser; +import org.apache.usergrid.java.client.auth.UsergridUserAuth; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.util.Map; + +import static org.apache.usergrid.java.client.utils.ObjectUtils.isEmpty; + +public class UsergridRequestManager { + + @NotNull public static String USERGRID_USER_AGENT = "usergrid-java/v" + Usergrid.UsergridSDKVersion; + + @NotNull private final UsergridClient usergridClient; + @NotNull private final OkHttpClient httpClient; + + public UsergridRequestManager(@NotNull final UsergridClient usergridClient) { + this.usergridClient = usergridClient; + this.httpClient = new OkHttpClient(); + } + + @NotNull + public UsergridResponse performRequest(@NotNull final UsergridRequest usergridRequest) { + Request request = usergridRequest.buildRequest(); + UsergridResponse usergridResponse; + try { + Response response = this.httpClient.newCall(request).execute(); + usergridResponse = UsergridResponse.fromResponse(this.usergridClient,usergridRequest,response); + } catch( IOException exception ) { + usergridResponse = UsergridResponse.fromException(this.usergridClient,exception); + } + return usergridResponse; + } + + @NotNull + private UsergridResponse authenticate(@NotNull final UsergridAuth auth) { + Map<String, String> credentials = auth.credentialsMap(); + String url = this.usergridClient.clientAppUrl(); + if ( auth instanceof UsergridUserAuth){ + + UsergridUserAuth userAuth = (UsergridUserAuth) auth; + if( userAuth.isAdminUser()){ + + url = this.usergridClient.managementUrl(); + } + + } + + UsergridRequest request = new UsergridRequest(UsergridHttpMethod.POST, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, url, null, credentials, this.usergridClient.authForRequests(), "token"); + UsergridResponse response = performRequest(request); + if (!isEmpty(response.getAccessToken()) && !isEmpty(response.getExpires())) { + auth.setAccessToken(response.getAccessToken()); + auth.setExpiry(System.currentTimeMillis() + response.getExpires() - 5000); + } + return response; + } + + @NotNull + public UsergridResponse authenticateApp(@NotNull final UsergridAppAuth appAuth) { + return this.authenticate(appAuth); + } + + @NotNull + public UsergridResponse authenticateUser(@NotNull final UsergridUserAuth userAuth) { + UsergridResponse response = this.authenticate(userAuth); + UsergridUser responseUser = response.user(); + if ( response.ok() && responseUser != null) { + responseUser.setUserAuth(userAuth); + } + return response; + } +} http://git-wip-us.apache.org/repos/asf/usergrid-java/blob/88039bad/src/main/java/org/apache/usergrid/java/client/auth/UsergridAppAuth.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/usergrid/java/client/auth/UsergridAppAuth.java b/src/main/java/org/apache/usergrid/java/client/auth/UsergridAppAuth.java new file mode 100644 index 0000000..a7ac64d --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/auth/UsergridAppAuth.java @@ -0,0 +1,55 @@ +/* + * 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.java.client.auth; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; + +@SuppressWarnings("unused") +public class UsergridAppAuth extends UsergridAuth { + + @NotNull private String clientId; + @NotNull private String clientSecret; + + @NotNull public String getClientId() { return clientId; } + public void setClientId(@NotNull final String clientId) { this.clientId = clientId; } + + @NotNull private String getClientSecret() { return clientSecret; } + public void setClientSecret(@NotNull final String clientSecret) { this.clientSecret = clientSecret; } + + @NotNull + @Override + public HashMap<String, String> credentialsMap() { + HashMap<String,String> credentials = super.credentialsMap(); + credentials.put("grant_type", "client_credentials"); + credentials.put("client_id", this.clientId); + credentials.put("client_secret", this.clientSecret); + return credentials; + } + + public UsergridAppAuth() { + this("",""); + } + + public UsergridAppAuth(@JsonProperty("clientId") @NotNull final String clientId, @JsonProperty("clientSecret") @NotNull final String clientSecret) { + super(); + this.clientId = clientId; + this.clientSecret = clientSecret; + } +} http://git-wip-us.apache.org/repos/asf/usergrid-java/blob/88039bad/src/main/java/org/apache/usergrid/java/client/auth/UsergridAuth.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/usergrid/java/client/auth/UsergridAuth.java b/src/main/java/org/apache/usergrid/java/client/auth/UsergridAuth.java new file mode 100644 index 0000000..1ed61da --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/auth/UsergridAuth.java @@ -0,0 +1,76 @@ +/* + * 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.java.client.auth; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; + +@SuppressWarnings("unused") +public class UsergridAuth { + + @Nullable private String accessToken = null; + @Nullable private Long expiry = null; + private boolean usingToken = false; + private boolean isAdminUser = false; + + public UsergridAuth() { } + + public UsergridAuth(@JsonProperty("accessToken") @Nullable final String accessToken) { + this.usingToken = true; + setAccessToken(accessToken); + } + + public UsergridAuth(@JsonProperty("accessToken") @Nullable final String accessToken, @JsonProperty("expiry") @Nullable final Long expiry) { + this.usingToken = true; + setAccessToken(accessToken); + setExpiry(expiry); + } + + public void destroy() { + setAccessToken(null); + setExpiry(null); + } + + @Nullable public String getAccessToken() { return accessToken; } + public void setAccessToken(@Nullable final String accessToken) { + this.accessToken = accessToken; + } + + @Nullable public Long getExpiry() { return expiry; } + public void setExpiry(@Nullable final Long tokenExpiry) { this.expiry = tokenExpiry; } + + public boolean isValidToken() { return (hasToken() && !isExpired()); } + + public boolean hasToken() { return accessToken != null; } + + public boolean isExpired() { + if (expiry != null) { + Long currentTime = System.currentTimeMillis() / 1000; + return ((expiry / 1000) < currentTime); + } else { + return !this.usingToken; + } + } + + @NotNull + public HashMap<String,String> credentialsMap() { + return new HashMap<>(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid-java/blob/88039bad/src/main/java/org/apache/usergrid/java/client/auth/UsergridUserAuth.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/usergrid/java/client/auth/UsergridUserAuth.java b/src/main/java/org/apache/usergrid/java/client/auth/UsergridUserAuth.java new file mode 100644 index 0000000..7cb42ad --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/auth/UsergridUserAuth.java @@ -0,0 +1,68 @@ +/* + * 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.java.client.auth; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; + +@SuppressWarnings("unused") +public class UsergridUserAuth extends UsergridAuth { + + @NotNull private String username; + @NotNull private String password; + private boolean isAdminUser = false; + + @NotNull public String getUsername() { return username; } + public void setUsername(@NotNull final String username) { this.username = username; } + + @NotNull private String getPassword() { return password; } + public void setPassword(@NotNull final String password) { this.password = password; } + + public boolean isAdminUser() { return isAdminUser; } + + @NotNull + @Override + public HashMap<String, String> credentialsMap() { + HashMap<String,String> credentials = super.credentialsMap(); + credentials.put("grant_type", "password"); + credentials.put("username", this.username); + credentials.put("password", this.password); + return credentials; + } + + public UsergridUserAuth() { + this("",""); + } + + public UsergridUserAuth(@JsonProperty("username") @NotNull final String username, + @JsonProperty("password") @NotNull final String password) { + super(); + this.username = username; + this.password = password; + } + + public UsergridUserAuth(@JsonProperty("username") @NotNull final String username, + @JsonProperty("password") @NotNull final String password, + @JsonProperty("isAdminUser") final boolean isAdminUser) { + super(); + this.username = username; + this.password = password; + this.isAdminUser = isAdminUser; + } +} http://git-wip-us.apache.org/repos/asf/usergrid-java/blob/88039bad/src/main/java/org/apache/usergrid/java/client/exception/UsergridException.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/usergrid/java/client/exception/UsergridException.java b/src/main/java/org/apache/usergrid/java/client/exception/UsergridException.java new file mode 100644 index 0000000..ff30a0d --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/exception/UsergridException.java @@ -0,0 +1,50 @@ +/* + * 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.java.client.exception; + +import org.jetbrains.annotations.NotNull; + +@SuppressWarnings("unused") +public class UsergridException extends RuntimeException { + + private int responseCode; + + public int getResponseCode() { + return responseCode; + } + public void setResponseCode(final int responseCode) { this.responseCode = responseCode; } + + private UsergridException() {} + + public UsergridException(@NotNull final String message) { + super(message); + } + + public UsergridException(@NotNull final String message, @NotNull final Throwable cause) { + super(message, cause); + } + + public UsergridException(@NotNull final String message, final int responseCode) { + super(message); + this.responseCode = responseCode; + } + + public UsergridException(@NotNull final String message, @NotNull final Throwable cause, final int responseCode) { + super(message, cause); + this.responseCode = responseCode; + } +} http://git-wip-us.apache.org/repos/asf/usergrid-java/blob/88039bad/src/main/java/org/apache/usergrid/java/client/model/UsergridDevice.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/usergrid/java/client/model/UsergridDevice.java b/src/main/java/org/apache/usergrid/java/client/model/UsergridDevice.java new file mode 100644 index 0000000..1833afb --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/model/UsergridDevice.java @@ -0,0 +1,60 @@ +package org.apache.usergrid.java.client.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.JsonNode; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +@SuppressWarnings("unused") +public class UsergridDevice extends UsergridEntity { + @NotNull public static String DEVICE_ENTITY_TYPE = "device"; + + @Nullable private String model; + @Nullable private String platform; + @Nullable private String osVersion; + + public UsergridDevice() { + super(DEVICE_ENTITY_TYPE); + } + + public UsergridDevice(@Nullable final String name) { + super(DEVICE_ENTITY_TYPE,name); + } + + public UsergridDevice(@NotNull final Map<String, JsonNode> properties) { + super(DEVICE_ENTITY_TYPE,null,properties); + } + + public UsergridDevice(@Nullable final String name, @NotNull final Map<String, JsonNode> properties) { + super(DEVICE_ENTITY_TYPE,name,properties); + } + + @Nullable @JsonProperty("deviceModel") + public String getModel() { + return this.model; + } + @JsonProperty("deviceModel") + public void setModel(@Nullable final String model) { + this.model = model; + } + + @Nullable @JsonProperty("devicePlatform") + public String getPlatform() { + return this.platform; + } + @JsonProperty("devicePlatform") + public void setPlatform(@Nullable final String platform) { + this.platform = platform; + } + + @Nullable @JsonProperty("deviceOSVersion") + public String getOsVersion() { + return this.osVersion; + } + @JsonProperty("deviceOSVersion") + public void setOsVersion(@Nullable final String osVersion) { + this.osVersion = osVersion; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid-java/blob/88039bad/src/main/java/org/apache/usergrid/java/client/model/UsergridEntity.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/usergrid/java/client/model/UsergridEntity.java b/src/main/java/org/apache/usergrid/java/client/model/UsergridEntity.java new file mode 100644 index 0000000..3444de0 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/model/UsergridEntity.java @@ -0,0 +1,487 @@ +/* + * 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.java.client.model; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.node.*; +import org.apache.usergrid.java.client.UsergridEnums.*; +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.UsergridClient; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.apache.usergrid.java.client.utils.JsonUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.*; + +import static org.apache.usergrid.java.client.utils.JsonUtils.*; + +@SuppressWarnings("unused") +public class UsergridEntity { + + @NotNull private static final HashMap<String,Class<? extends UsergridEntity>> subclassMappings = new HashMap<>(); + @NotNull private static final ObjectMapper entityUpdateMapper = new ObjectMapper(); + @NotNull private final ObjectReader entityUpdateReader = entityUpdateMapper.readerForUpdating(this); + + static { + subclassMappings.put("user",UsergridUser.class); + subclassMappings.put("device",UsergridDevice.class); + } + + @NotNull private String type; + @Nullable private String uuid; + @Nullable private String name; + @Nullable private Long created; + @Nullable private Long modified; + + @NotNull private Map<String, JsonNode> properties = new HashMap<>(); + + public UsergridEntity(@JsonProperty("type") @NotNull final String type) { + this.type = type; + } + + public UsergridEntity(@NotNull final String type, @Nullable final String name) { + this(type); + if( name != null ) { + this.name = name; + } + } + + public UsergridEntity(@NotNull final String type, @Nullable final String name, @NotNull final Map<String, ?> properties) { + this(type,name); + this.updatePropertiesWithMap(properties); + } + + @Nullable + public static Class<? extends UsergridEntity> customSubclassForType(@NotNull final String type) { + return UsergridEntity.subclassMappings.get(type); + } + + public void copyAllProperties(@NotNull final UsergridEntity fromEntity) { + try { + this.updatePropertiesWithJsonNode(entityUpdateMapper.valueToTree(fromEntity)); + } catch( IllegalArgumentException e ) { System.out.print("Usergrid Error: Unable to update properties from entity - " + fromEntity.toString()); } + } + + public void updatePropertiesWithMap(@NotNull final Map<String,?> properties) { + try { + this.updatePropertiesWithJsonNode(entityUpdateMapper.valueToTree(properties)); + } catch( IllegalArgumentException e ) { System.out.print("Usergrid Error: Unable to update properties from map - " + properties.toString()); } + } + + public void updatePropertiesWithJsonNode(@NotNull final JsonNode node) { + try { + entityUpdateReader.readValue(node); + } catch( IOException e ) { System.out.print("Usergrid Error: Unable to update properties from jsonNode - " + node.toString()); } + } + + public static void mapCustomSubclassToType(@NotNull final String type, @NotNull final Class<? extends UsergridEntity> subclass) { + UsergridEntity.subclassMappings.put(type,subclass); + } + + @NotNull @Override public String toString() { + return toJsonString(this); + } + @NotNull public String toPrettyString() { return toPrettyJsonString(this); } + @NotNull public JsonNode toJsonObjectValue() { + return toJsonNode(this); + } + @SuppressWarnings("unchecked") + @NotNull public Map<String,?> toMapValue() { return toMap(this); } + + @JsonIgnore + public boolean isUser() { return (this instanceof UsergridUser || this.getType().equalsIgnoreCase(UsergridUser.USER_ENTITY_TYPE)); } + + @NotNull public String getType() { return this.type; } + private void setType(@NotNull final String type) { this.type = type; } + + @Nullable public String getUuid() { return this.uuid; } + private void setUuid(@NotNull final String uuid) { this.uuid = uuid; } + + @Nullable public String getName() { return this.name; } + protected void setName(@Nullable final String name) { this.name = name; } + + @Nullable public Long getCreated() { return this.created; } + private void setCreated(@NotNull final Long created) { this.created = created; } + + @Nullable public Long getModified() { return this.modified; } + private void setModified(@NotNull final Long modified) { this.modified = modified; } + + public void setLocation(final double latitude, final double longitude) { + ObjectNode rootNode = JsonUtils.createObjectNode(); + rootNode.put("latitude", latitude); + rootNode.put("longitude", longitude); + setObjectProperty(this.properties, "location", rootNode); + } + + @Nullable + public String uuidOrName() { + String uuidOrName = this.getUuid(); + if( uuidOrName == null ) { + uuidOrName = this.getName(); + } + return uuidOrName; + } + + @NotNull + public UsergridResponse reload() { + return this.reload(Usergrid.getInstance()); + } + + @NotNull + public UsergridResponse reload(@NotNull final UsergridClient client) { + String uuidOrName = this.uuidOrName(); + if( uuidOrName == null ) { + return UsergridResponse.fromError(client, "No UUID or name found.", "The entity object must have a `uuid` or `name` assigned."); + } + UsergridResponse response = client.GET(this.getType(), uuidOrName); + if( response.ok() ) { + UsergridEntity responseEntity = response.first(); + if( responseEntity != null ) { + this.copyAllProperties(responseEntity); + } + } + return response; + } + + @NotNull + public UsergridResponse save() { + return this.save(Usergrid.getInstance()); + } + + @NotNull + public UsergridResponse save(@NotNull final UsergridClient client) { + UsergridResponse response; + if( this.getUuid() != null ) { + response = client.PUT(this); + } else { + response = client.POST(this); + } + if( response.ok() ) { + UsergridEntity responseEntity = response.first(); + if( responseEntity != null ) { + this.copyAllProperties(responseEntity); + } + } + return response; + } + + @NotNull + public UsergridResponse remove() { + return this.remove(Usergrid.getInstance()); + } + + @NotNull + public UsergridResponse remove(@NotNull final UsergridClient client) { + return client.DELETE(this); + } + + @NotNull + public UsergridResponse connect(@NotNull final String relationship, @NotNull final UsergridEntity toEntity) { + return this.connect(Usergrid.getInstance(), relationship, toEntity); + } + + @NotNull + public UsergridResponse connect(@NotNull final UsergridClient client, @NotNull final String relationship, @NotNull final UsergridEntity toEntity) { + return client.connect(this,relationship,toEntity); + } + + @NotNull + public UsergridResponse disconnect(@NotNull final String relationship, @NotNull final UsergridEntity fromEntity) { + return this.disconnect(Usergrid.getInstance(), relationship, fromEntity); + } + + @NotNull + public UsergridResponse disconnect(@NotNull final UsergridClient client, @NotNull final String relationship, @NotNull final UsergridEntity fromEntity) { + return client.disconnect(this,relationship,fromEntity); + } + + @NotNull + public UsergridResponse getConnections(@NotNull final UsergridDirection direction, @NotNull final String relationship) { + return this.getConnections(Usergrid.getInstance(),direction,relationship); + } + + @NotNull + public UsergridResponse getConnections(@NotNull final UsergridClient client, @NotNull final UsergridDirection direction, @NotNull final String relationship) { + return client.getConnections(direction,this,relationship); + } + + public void removeProperty(@NotNull final String name) { + putProperty(name, NullNode.getInstance()); + } + + public void removeProperties(@NotNull final List<String> names) { + for( String propertyName : names ) { + this.removeProperty(propertyName); + } + } + + public void putProperty(@NotNull final String name, @NotNull final String value) { + this.putProperty(name, JsonNodeFactory.instance.textNode(value)); + } + public void putProperty(@NotNull final String name, final boolean value) { + this.putProperty(name, JsonNodeFactory.instance.booleanNode(value)); + } + public void putProperty(@NotNull final String name, @NotNull final List value) { + this.putProperty(name, JsonNodeFactory.instance.pojoNode(value)); + } + public void putProperty(@NotNull final String name, final int value) { + this.putProperty(name, JsonNodeFactory.instance.numberNode(value)); + } + public void putProperty(@NotNull final String name, final long value) { + this.putProperty(name, JsonNodeFactory.instance.numberNode(value)); + } + public void putProperty(@NotNull final String name, final float value) { + this.putProperty(name, JsonNodeFactory.instance.numberNode(value)); + } + public void putProperty(@NotNull final String name, @Nullable final JsonNode value) { + UsergridEntityProperties entityProperty = UsergridEntityProperties.fromString(name); + if( entityProperty != null && !entityProperty.isMutableForEntity(this)) { + return; + } + + JsonNode valueNode = value; + if( valueNode == null ) { + valueNode = NullNode.getInstance(); + } + this.updatePropertiesWithMap(Collections.singletonMap(name,valueNode)); + } + public void putProperties(@NotNull final String jsonString) { + try { + JsonNode jsonNode = entityUpdateMapper.readTree(jsonString); + this.putProperties(jsonNode); + } catch( Exception ignore ) {} + } + public void putProperties(@NotNull final Map<String, Object> properties) { + try { + JsonNode jsonNode = entityUpdateMapper.valueToTree(properties); + this.putProperties(jsonNode); + } catch( Exception ignore ) {} + } + public void putProperties(@NotNull final JsonNode jsonNode) { + HashMap<String,JsonNode> propertiesToUpdate = new HashMap<>(); + Iterator<Map.Entry<String,JsonNode>> keys = jsonNode.fields(); + while (keys.hasNext()) { + Map.Entry<String,JsonNode> entry = keys.next(); + String key = entry.getKey(); + UsergridEntityProperties entityProperty = UsergridEntityProperties.fromString(key); + if( entityProperty == null || entityProperty.isMutableForEntity(this) ) { + propertiesToUpdate.put(key,entry.getValue()); + } + } + if( !propertiesToUpdate.isEmpty() ) { + this.updatePropertiesWithMap(propertiesToUpdate); + } + } + + @SuppressWarnings("unchecked") + public void append(@NotNull final String name, @NotNull final Object value) { + this.append(name, (value instanceof List) ? (List<Object>) value : Collections.singletonList(value)); + } + + public void append(@NotNull final String name, @NotNull final List<Object> value) { + this.insert(name, value, Integer.MAX_VALUE); + } + + @SuppressWarnings("unchecked") + public void insert(@NotNull final String name, @NotNull final Object value) { + this.insert(name, (value instanceof List) ? (List<Object>) value : Collections.singletonList(value), 0); + } + + @SuppressWarnings("unchecked") + public void insert(@NotNull final String name, @NotNull final Object value, final int index) { + this.insert(name, (value instanceof List) ? (List<Object>) value : Collections.singletonList(value), index); + } + + public void insert(@NotNull final String name, @NotNull final List<Object> value) { + this.insert(name,value,0); + } + + public void insert(@NotNull final String name, @NotNull final List<Object> value, final int index) { + int indexToInsert = index; + if (indexToInsert < 0) { + indexToInsert = 0; + } + Object propertyValue = this.getEntityProperty(name); + if( propertyValue != null ) { + ArrayList<Object> propertyArrayValue = this.convertToList(propertyValue); + propertyArrayValue = this.insertIntoArray(propertyArrayValue,value,indexToInsert); + this.putProperty(name, propertyArrayValue); + } else { + this.putProperty(name, value); + } + } + + public void pop(@NotNull final String name) { + ArrayList<Object> arrayToPop = this.getArrayToPopOrShift(name); + if( arrayToPop != null && !arrayToPop.isEmpty() ) { + arrayToPop.remove(arrayToPop.size() - 1); + this.putProperty(name, arrayToPop); + } + } + + public void shift(@NotNull final String name) { + ArrayList<Object> arrayToShift = this.getArrayToPopOrShift(name); + if( arrayToShift != null && !arrayToShift.isEmpty() ) { + arrayToShift.remove(0); + this.putProperty(name, arrayToShift); + } + } + + @Nullable + public <T> T getEntityProperty(@NotNull final String name) { + return JsonUtils.getProperty(this.properties, name); + } + + @Nullable + public JsonNode getJsonNodeProperty(@NotNull final String name) { + return this.getProperties().get(name); + } + + @Nullable + public String getStringProperty(@NotNull final String name) { + return JsonUtils.getStringProperty(this.getProperties(), name); + } + + @Nullable + public Boolean getBooleanProperty(@NotNull final String name) { + Boolean booleanValue = null; + Object object = JsonUtils.getProperty(this.getProperties(), name); + if( object instanceof Boolean ) { + booleanValue = (Boolean)object; + } + return booleanValue; + } + + @Nullable + public Number getNumberProperty(@NotNull final String name) { + Number numberValue = null; + Object object = JsonUtils.getProperty(this.getProperties(), name); + if( object instanceof Number ) { + numberValue = (Number)object; + } + return numberValue; + } + + @Nullable + public Integer getIntegerProperty(@NotNull final String name) { + Integer integerValue = null; + Object object = JsonUtils.getProperty(this.getProperties(), name); + if( object instanceof Number ) { + integerValue = ((Number)object).intValue(); + } + return integerValue; + } + + @Nullable + public Float getFloatProperty(@NotNull final String name) { + Float floatValue = null; + Object object = JsonUtils.getProperty(this.getProperties(), name); + if( object instanceof Number ) { + floatValue = ((Number)object).floatValue(); + } + return floatValue; + } + + @Nullable + public Long getLongProperty(@NotNull final String name) { + Long longValue = null; + Object object = JsonUtils.getProperty(this.getProperties(), name); + if( object instanceof Number ) { + longValue = ((Number)object).longValue(); + } + return longValue; + } + + @JsonAnyGetter @NotNull + public Map<String, JsonNode> getProperties() { + return this.properties; + } + + @JsonAnySetter + private void internalPutProperty(@NotNull final String name, @Nullable final JsonNode value) { + if (value == null) { + properties.put(name, NullNode.instance); + } else { + properties.put(name, value); + } + } + + @Nullable + @SuppressWarnings("unchecked") + private ArrayList<Object> getArrayToPopOrShift(@NotNull final String name) { + Object entityProperty = getEntityProperty(name); + ArrayList<Object> arrayToPopOrShift = null; + if (entityProperty instanceof POJONode) { + Object objectValue = ((POJONode) entityProperty).getPojo(); + if (objectValue instanceof List) { + arrayToPopOrShift = new ArrayList<>((List) objectValue); + } else { + arrayToPopOrShift = new ArrayList<>(); + arrayToPopOrShift.add(objectValue); + } + } else if( entityProperty instanceof ArrayNode ) { + arrayToPopOrShift = JsonUtils.convertToArrayList((ArrayNode)entityProperty); + } else if( entityProperty instanceof List ) { + arrayToPopOrShift = new ArrayList<>((List) entityProperty); + } + return arrayToPopOrShift; + } + + @NotNull + private ArrayList<Object> convertToList(@NotNull final Object value) { + ArrayList<Object> arrayList = new ArrayList<>(); + if( value instanceof ArrayNode ) { + arrayList = JsonUtils.convertToArrayList((ArrayNode)value); + } else if (value instanceof POJONode) { + Object objectValue = ((POJONode) value).getPojo(); + if( objectValue instanceof List ) { + arrayList.addAll((List)objectValue); + } else { + arrayList.add(objectValue); + } + } else if (value instanceof List) { + arrayList.addAll((List)value); + } else { + arrayList.add(value); + } + return arrayList; + } + + @NotNull + private ArrayList<Object> insertIntoArray(@NotNull final List<Object> propertyArrayNode, @NotNull final List<Object> arrayToInsert, final int index) { + ArrayList<Object> mergedArray = new ArrayList<>(); + if (propertyArrayNode.size() <= 0 || arrayToInsert.isEmpty()) { + mergedArray.addAll(arrayToInsert); + } else if ( index <= 0 ) { + mergedArray.addAll(arrayToInsert); + mergedArray.addAll(propertyArrayNode); + } else if ( index > 0 ) { + mergedArray.addAll(propertyArrayNode); + if ( index > propertyArrayNode.size() ) { + mergedArray.addAll(arrayToInsert); + } else { + mergedArray.addAll(index,arrayToInsert); + } + } + return mergedArray; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid-java/blob/88039bad/src/main/java/org/apache/usergrid/java/client/model/UsergridUser.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/usergrid/java/client/model/UsergridUser.java b/src/main/java/org/apache/usergrid/java/client/model/UsergridUser.java new file mode 100644 index 0000000..f967e46 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/model/UsergridUser.java @@ -0,0 +1,198 @@ +/* + * 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.java.client.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import org.apache.usergrid.java.client.Usergrid; +import org.apache.usergrid.java.client.UsergridClient; +import org.apache.usergrid.java.client.UsergridEnums.*; +import org.apache.usergrid.java.client.auth.UsergridUserAuth; +import org.apache.usergrid.java.client.query.UsergridQuery; +import org.apache.usergrid.java.client.response.UsergridResponse; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; + +@SuppressWarnings("unused") +@JsonInclude(JsonInclude.Include.NON_NULL) +public class UsergridUser extends UsergridEntity { + @NotNull public final static String USER_ENTITY_TYPE = "user"; + + @Nullable private UsergridUserAuth userAuth = null; + + @Nullable private String username; + @Nullable private String email; + @Nullable private String password; + @Nullable private String picture; + + private boolean activated = false; + private boolean disabled = false; + + public UsergridUser() { + super(USER_ENTITY_TYPE); + } + + public UsergridUser(@NotNull final String username, @Nullable final String password) { + super(USER_ENTITY_TYPE); + setUsername(username); + setPassword(password); + } + + public UsergridUser(@NotNull final String name, @NotNull final HashMap<String, Object> propertyMap) { + super(USER_ENTITY_TYPE,name); + putProperties(propertyMap); + } + + public UsergridUser(@Nullable final String name, @Nullable final String username, @Nullable final String email, @Nullable final String password) { + super(USER_ENTITY_TYPE,name); + setUsername(username); + setEmail(email); + setPassword(password); + } + + public void setName(@Nullable final String name) { super.setName(name); } + + @Nullable public String getUsername() { return this.username; } + public void setUsername(@Nullable final String username) { this.username = username; } + + @Nullable public String getEmail() { return this.email; } + public void setEmail(@Nullable final String email) { this.email = email; } + + @Nullable public String getPassword() { return this.password; } + public void setPassword(@Nullable final String password) { this.password = password; } + + @Nullable public String getPicture() { return this.picture; } + public void setPicture(@Nullable final String picture) { this.picture = picture; } + + public boolean isActivated() { return this.activated; } + public void setActivated(final boolean activated) { this.activated = activated; } + + public boolean isDisabled() { return this.disabled; } + public void setDisabled(final boolean disabled) { this.disabled = disabled; } + + @JsonIgnore @Nullable public UsergridUserAuth getUserAuth() { return this.userAuth; } + @JsonIgnore public void setUserAuth(@Nullable final UsergridUserAuth userAuth) { this.userAuth = userAuth; } + + @Nullable + public String uuidOrUsername() { + String uuidOrUsername = this.getUuid(); + if( uuidOrUsername == null ) { + uuidOrUsername = this.getUsername(); + } + return uuidOrUsername; + } + + @Nullable + public String usernameOrEmail() { + String usernameOrEmail = this.getUsername(); + if( usernameOrEmail == null ) { + usernameOrEmail = this.getEmail(); + } + return usernameOrEmail; + } + + public static boolean checkAvailable(@Nullable final String email, @Nullable final String username) { + return UsergridUser.checkAvailable(Usergrid.getInstance(), email, username); + } + + public static boolean checkAvailable(@NotNull final UsergridClient client, @Nullable final String email, @Nullable final String username) { + if (email == null && username == null) { + throw new IllegalArgumentException("email and username both are null "); + } + UsergridQuery query = new UsergridQuery(USER_ENTITY_TYPE); + if (username != null) { + query.eq(UsergridUserProperties.USERNAME.toString(), username); + } + if (email != null) { + query.or().eq(UsergridUserProperties.EMAIL.toString(), email); + } + return client.GET(query).first() != null; + } + + @NotNull + public UsergridResponse create() { + return this.create(Usergrid.getInstance()); + } + + @NotNull + public UsergridResponse create(@NotNull final UsergridClient client) { + UsergridResponse response = client.POST(this); + UsergridUser createdUser = response.user(); + if( createdUser != null ) { + this.copyAllProperties(createdUser); + } + return response; + } + + @NotNull + public UsergridResponse login(@NotNull final String username, @NotNull final String password) { + return this.login(Usergrid.getInstance(),username,password); + } + + @NotNull + public UsergridResponse login(@NotNull final UsergridClient client, @NotNull final String username, @NotNull final String password) { + UsergridUserAuth userAuth = new UsergridUserAuth(username,password); + UsergridResponse response = client.authenticateUser(userAuth,false); + if( response.ok() ) { + this.userAuth = userAuth; + } + return response; + } + + @NotNull + public UsergridResponse resetPassword(@NotNull final String oldPassword, @NotNull final String newPassword) { + return this.resetPassword(Usergrid.getInstance(),oldPassword,newPassword); + } + + @NotNull + public UsergridResponse resetPassword(@NotNull final UsergridClient client, @NotNull final String oldPassword, @NotNull final String newPassword) { + return client.resetPassword(this,oldPassword,newPassword); + } + + @NotNull + public UsergridResponse reauthenticate() { + return this.reauthenticate(Usergrid.getInstance()); + } + + @NotNull + public UsergridResponse reauthenticate(@NotNull final UsergridClient client) { + return this.userAuth == null ? UsergridResponse.fromError(client, "Invalid UsergridUserAuth.", "No UsergridUserAuth found on the UsergridUser.") : client.authenticateUser(this.userAuth, false); + } + + @NotNull + public UsergridResponse logout() { + return this.logout(Usergrid.getInstance()); + } + + @NotNull + public UsergridResponse logout(@NotNull final UsergridClient client) { + UsergridResponse response; + String uuidOrUsername = this.uuidOrUsername(); + String accessToken = (this.userAuth != null) ? this.userAuth.getAccessToken() : null; + if (uuidOrUsername == null || accessToken == null ) { + response = UsergridResponse.fromError(client, "Logout Failed.", "UUID or Access Token not found on UsergridUser object."); + } else { + response = client.logoutUser(uuidOrUsername, accessToken); + if( response.ok() ) { + this.userAuth = null; + } + } + return response; + } +} http://git-wip-us.apache.org/repos/asf/usergrid-java/blob/88039bad/src/main/java/org/apache/usergrid/java/client/query/UsergridQuery.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/usergrid/java/client/query/UsergridQuery.java b/src/main/java/org/apache/usergrid/java/client/query/UsergridQuery.java new file mode 100644 index 0000000..e8c78c2 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/query/UsergridQuery.java @@ -0,0 +1,431 @@ +/* + * 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.java.client.query; + +import org.apache.usergrid.java.client.UsergridEnums.UsergridQueryOperator; +import org.apache.usergrid.java.client.UsergridEnums.UsergridQuerySortOrder; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.net.URLEncoder; +import java.util.*; + +@SuppressWarnings("unused") +public final class UsergridQuery { + + @NotNull private final ArrayList<String> requirementStrings = new ArrayList<>(); + @NotNull private final ArrayList<String> urlTerms = new ArrayList<>(); + @NotNull private final HashMap<String, UsergridQuerySortOrder> orderClauses = new HashMap<>(); + @NotNull private Integer limit = UsergridQuery.LIMIT_DEFAULT; + @Nullable private String cursor = null; + @Nullable private String fromStringValue = null; + @Nullable private String collectionName = null; + + public UsergridQuery() { + this(null); + } + + public UsergridQuery(@Nullable final String collectionName) { + this.collectionName = collectionName; + this.requirementStrings.add(UsergridQuery.EMPTY_STRING); + } + + private static boolean isUUID(@NotNull final String string) { + try { + UUID uuid = UUID.fromString(string); + return true; + } catch (Exception ex) { + return false; + } + } + + @NotNull + private static String encode(@NotNull final String stringValue) { + String escapedString; + try { + escapedString = URLEncoder.encode(stringValue, UTF8); + } catch (Exception e) { + escapedString = stringValue; + } + return escapedString; + } + + @NotNull + public static String strJoin(@NotNull final List<String> array, @NotNull final String separator) { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0, il = array.size(); i < il; i++) { + if (i > 0) { + stringBuilder.append(separator); + } + stringBuilder.append(array.get(i)); + } + return stringBuilder.toString(); + } + + @NotNull + public UsergridQuery fromString(@NotNull final String stringValue) { + this.fromStringValue = stringValue; + return this; + } + + @Nullable + public String getType() { + return this.collectionName; + } + + @Nullable + public String getCollectionName() { + return this.collectionName; + } + + @Nullable + public String getCollection() { + return this.collectionName; + } + + @NotNull + public UsergridQuery type(@Nullable final String type) { + this.collectionName = type; + return this; + } + + @NotNull + public UsergridQuery collection(@Nullable final String collectionName) { + return this.type(collectionName); + } + + @NotNull + public UsergridQuery collectionName(@Nullable final String collectionName) { + return this.type(collectionName); + } + + @NotNull + public UsergridQuery cursor(@Nullable final String value) { + this.cursor = value; + return this; + } + + @NotNull + public UsergridQuery limit(@NotNull final Integer limit) { + this.limit = limit; + return this; + } + + @NotNull + private UsergridQuery addConditionalSeparator(@NotNull final String separator) { + if (!this.requirementStrings.get(0).isEmpty()) { + this.requirementStrings.add(0, separator); + this.requirementStrings.add(0, UsergridQuery.EMPTY_STRING); + } + return this; + } + + @NotNull + public UsergridQuery and() { + return this.addConditionalSeparator(UsergridQuery.AND); + } + + @NotNull + public UsergridQuery or() { + return this.addConditionalSeparator(UsergridQuery.OR); + } + + @NotNull + public UsergridQuery not() { + return this.addConditionalSeparator(UsergridQuery.NOT); + } + + @NotNull + public UsergridQuery sort(@NotNull final String term, @NotNull final UsergridQuerySortOrder sortOrder) { + this.orderClauses.put(term, sortOrder); + return this; + } + + @NotNull + public UsergridQuery ascending(@NotNull final String term) { + return this.asc(term); + } + + @NotNull + public UsergridQuery asc(@NotNull final String term) { + return this.sort(term, UsergridQuerySortOrder.ASC); + } + + @NotNull + public UsergridQuery descending(@NotNull final String term) { + return this.desc(term); + } + + @NotNull + public UsergridQuery desc(@NotNull final String term) { + return this.sort(term, UsergridQuerySortOrder.DESC); + } + + @NotNull + public UsergridQuery contains(@NotNull final String term, @NotNull final String value) { + return this.containsWord(term, value); + } + + @NotNull + public UsergridQuery containsString(@NotNull final String term, @NotNull final String value) { + return this.containsWord(term, value); + } + + @NotNull + public UsergridQuery containsWord(@NotNull final String term, @NotNull final String value) { + return this.addRequirement(term + SPACE + CONTAINS + SPACE + ((UsergridQuery.isUUID(value)) ? EMPTY_STRING : APOSTROPHE) + value + ((UsergridQuery.isUUID(value)) ? EMPTY_STRING : APOSTROPHE)); + } + + @NotNull + public UsergridQuery filter(@NotNull final String term, @NotNull final Object value) { + return this.eq(term, value); + } + + @NotNull + public UsergridQuery equals(@NotNull final String term, @NotNull final Object value) { + return this.eq(term, value); + } + + @NotNull + public UsergridQuery eq(@NotNull final String term, @NotNull final Object value) { + return this.addOperationRequirement(term, UsergridQueryOperator.EQUAL, value); + } + + @NotNull + public UsergridQuery greaterThan(@NotNull final String term, @NotNull final Object value) { + return this.gt(term, value); + } + + @NotNull + public UsergridQuery gt(@NotNull final String term, @NotNull final Object value) { + return this.addOperationRequirement(term, UsergridQueryOperator.GREATER_THAN, value); + } + + @NotNull + public UsergridQuery greaterThanOrEqual(@NotNull final String term, @NotNull final Object value) { + return this.gte(term, value); + } + + @NotNull + public UsergridQuery gte(@NotNull final String term, @NotNull final Object value) { + return this.addOperationRequirement(term, UsergridQueryOperator.GREATER_THAN_EQUAL_TO, value); + } + + @NotNull + public UsergridQuery lessThan(@NotNull final String term, @NotNull final Object value) { + return this.lt(term, value); + } + + @NotNull + public UsergridQuery lt(@NotNull final String term, @NotNull final Object value) { + return this.addOperationRequirement(term, UsergridQueryOperator.LESS_THAN, value); + } + + @NotNull + public UsergridQuery lessThanOrEqual(@NotNull final String term, @NotNull final Object value) { + return this.lte(term, value); + } + + @NotNull + public UsergridQuery lte(@NotNull final String term, @NotNull final Object value) { + return this.addOperationRequirement(term, UsergridQueryOperator.LESS_THAN_EQUAL_TO, value); + } + + @NotNull + public UsergridQuery locationWithin(final double distance, final double latitude, final double longitude) { + return this.addRequirement(LOCATION + SPACE + WITHIN + SPACE + distance + SPACE + OF + SPACE + latitude + SPACE + COMMA + longitude); + } + + @NotNull + public UsergridQuery urlTerm(@NotNull final String term, @NotNull final String equalsValue) { + if (term.equalsIgnoreCase(QL)) { + this.ql(equalsValue); + } else { + this.urlTerms.add(UsergridQuery.encode(term) + EQUALS + UsergridQuery.encode(equalsValue)); + } + return this; + } + + @NotNull + public UsergridQuery ql(final String value) { + + return value != null && !value.isEmpty() ? this.addRequirement(value) : this; + + } + + @NotNull + public UsergridQuery addRequirement(@NotNull final String requirement) { + String requirementString = this.requirementStrings.remove(0); + if (!requirement.isEmpty() && !requirementString.isEmpty()) { + requirementString += SPACE + AND + SPACE; + } + requirementString += requirement; + this.requirementStrings.add(0, requirementString); + return this; + } + + @NotNull + public UsergridQuery addOperationRequirement(@NotNull final String term, @NotNull final UsergridQueryOperator operation, final int intValue) { + return this.addOperationRequirement(term, operation, Integer.valueOf(intValue)); + } + + @NotNull + public UsergridQuery addOperationRequirement(@NotNull final String term, @NotNull final UsergridQueryOperator operation, @NotNull final Object value) { + if (value instanceof String) { + String valueString = value.toString(); + if (!UsergridQuery.isUUID(valueString)) { + valueString = APOSTROPHE + value + APOSTROPHE; + } + return addRequirement(term + SPACE + operation.operatorValue() + SPACE + valueString); + } else { + return addRequirement(term + SPACE + operation.operatorValue() + SPACE + value.toString()); + } + } + + @NotNull + private String constructOrderByString() { + String orderByString = EMPTY_STRING; + if (!this.orderClauses.isEmpty()) { + for (Map.Entry<String, UsergridQuerySortOrder> orderClause : this.orderClauses.entrySet()) { + if (!orderByString.isEmpty()) { + orderByString += COMMA; + } + orderByString += orderClause.getKey() + SPACE + orderClause.getValue().toString(); + } + if (!orderByString.isEmpty()) { + orderByString = SPACE + ORDER_BY + SPACE + orderByString; + } + } + return orderByString; + } + + @NotNull + private String constructURLTermsString() { + String urlTermsString = EMPTY_STRING; + if (!this.urlTerms.isEmpty()) { + urlTermsString = UsergridQuery.strJoin(this.urlTerms, AMPERSAND); + } + return urlTermsString; + } + + @NotNull + private String constructRequirementString() { + ArrayList<String> requirementStrings = new ArrayList<>(this.requirementStrings); + String firstString = requirementStrings.get(0); + if (firstString.isEmpty()) { + requirementStrings.remove(0); + } + String requirementsString = EMPTY_STRING; + if (!requirementStrings.isEmpty()) { + firstString = requirementStrings.get(0); + if (firstString.equalsIgnoreCase(OR) || firstString.equalsIgnoreCase(AND) || firstString.equalsIgnoreCase(NOT)) { + requirementStrings.remove(0); + } + if (!requirementStrings.isEmpty()) { + Collections.reverse(requirementStrings); + requirementsString = UsergridQuery.strJoin(requirementStrings, SPACE); + } + } + return requirementsString; + } + + @NotNull + private String constructURLAppend() { + return this.constructURLAppend(true); + } + + @NotNull + private String constructURLAppend(final boolean autoURLEncode) { + if (this.fromStringValue != null) { + String requirementsString = this.fromStringValue; + if (autoURLEncode) { + requirementsString = UsergridQuery.encode(requirementsString); + } + return QUESTION_MARK + QL + EQUALS + requirementsString; + } + String urlAppend = EMPTY_STRING; + if (this.limit != LIMIT_DEFAULT) { + urlAppend += LIMIT + EQUALS + this.limit.toString(); + } + String urlTermsString = this.constructURLTermsString(); + if (!urlTermsString.isEmpty()) { + if (!urlAppend.isEmpty()) { + urlAppend += AMPERSAND; + } + urlAppend += urlTermsString; + } + if (this.cursor != null && !this.cursor.isEmpty()) { + if (!urlAppend.isEmpty()) { + urlAppend += AMPERSAND; + } + urlAppend += CURSOR + EQUALS + this.cursor; + } + + String requirementsString = this.constructRequirementString(); + + String orderByString = this.constructOrderByString(); + if (!orderByString.isEmpty()) { + requirementsString += orderByString; + } + if (!requirementsString.isEmpty()) { + if (autoURLEncode) { + requirementsString = UsergridQuery.encode(requirementsString); + } + if (!urlAppend.isEmpty()) { + urlAppend += AMPERSAND; + } + urlAppend += QL + EQUALS + requirementsString; + } + if (!urlAppend.isEmpty()) { + urlAppend = QUESTION_MARK + urlAppend; + } + return urlAppend; + } + + @NotNull + public String build() { + return this.build(true); + } + + @NotNull + public String build(final boolean autoURLEncode) { + return this.constructURLAppend(autoURLEncode); + } + + private static final int LIMIT_DEFAULT = 10; + @NotNull private static final String AMPERSAND = "&"; + @NotNull private static final String AND = "and"; + @NotNull private static final String APOSTROPHE = "'"; + @NotNull private static final String COMMA = ","; + @NotNull private static final String CONTAINS = "contains"; + @NotNull private static final String CURSOR = "cursor"; + @NotNull private static final String EMPTY_STRING = ""; + @NotNull private static final String EQUALS = "="; + @NotNull private static final String LIMIT = "limit"; + @NotNull private static final String LOCATION = "location"; + @NotNull private static final String NOT = "not"; + @NotNull private static final String OF = "of"; + @NotNull private static final String OR = "or"; + @NotNull private static final String ORDER_BY = "order by"; + @NotNull private static final String QL = "ql"; + @NotNull private static final String QUESTION_MARK = "?"; + @NotNull private static final String SELECT_ALL = "select *"; + @NotNull private static final String SPACE = " "; + @NotNull private static final String UTF8 = "UTF-8"; + @NotNull private static final String WHERE = "where"; + @NotNull private static final String WITHIN = "within"; +} http://git-wip-us.apache.org/repos/asf/usergrid-java/blob/88039bad/src/main/java/org/apache/usergrid/java/client/response/UsergridResponse.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/usergrid/java/client/response/UsergridResponse.java b/src/main/java/org/apache/usergrid/java/client/response/UsergridResponse.java new file mode 100644 index 0000000..ee649c4 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/response/UsergridResponse.java @@ -0,0 +1,230 @@ +/* + * 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.java.client.response; + +import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.databind.JsonNode; +import okhttp3.Headers; +import org.apache.usergrid.java.client.UsergridClient; +import org.apache.usergrid.java.client.UsergridEnums; +import org.apache.usergrid.java.client.UsergridRequest; +import org.apache.usergrid.java.client.model.UsergridEntity; +import org.apache.usergrid.java.client.model.UsergridUser; +import org.apache.usergrid.java.client.query.UsergridQuery; +import org.apache.usergrid.java.client.utils.JsonUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +import static org.apache.usergrid.java.client.utils.JsonUtils.toJsonString; + +@SuppressWarnings("unused") +@JsonInclude(JsonInclude.Include.NON_NULL) +public class UsergridResponse { + + @Nullable private UsergridClient client; + @NotNull private Map<String, JsonNode> properties = new HashMap<>(); + + private int statusCode = 0; + @Nullable private JsonNode responseJson = null; + @Nullable private String cursor; + @Nullable private List<UsergridEntity> entities; + @Nullable private Map<String, String> headers; + @Nullable private UsergridQuery query; + @Nullable private UsergridResponseError responseError = null; + + @Nullable private String accessToken; + @Nullable private Long expires; + + public boolean ok() { return (statusCode > 0 && statusCode < 400); } + public int count() { return (entities == null) ? 0 : entities.size(); } + public boolean hasNextPage() { return (cursor != null); } + @NotNull @Override public String toString() { + return toJsonString(this); + } + + @Nullable public UsergridEntity first() { return (entities == null || entities.isEmpty()) ? null : entities.get(0); } + @Nullable public UsergridEntity entity() { + return first(); + } + @Nullable public UsergridEntity last() { return (entities == null || entities.isEmpty()) ? null : entities.get(entities.size() - 1); } + + @Nullable + public UsergridUser user() { + UsergridEntity entity = this.first(); + if( entity != null && entity instanceof UsergridUser ) { + return (UsergridUser) entity; + } + return null; + } + + @Nullable + public List<UsergridUser> users() { + ArrayList<UsergridUser> users = null; + if( entities != null && !entities.isEmpty() ) { + for( UsergridEntity entity : entities ) { + if( entity instanceof UsergridUser ) { + if( users == null ) { + users = new ArrayList<>(); + } + users.add((UsergridUser)entity); + } + } + } + return users; + } + + public int getStatusCode() { return this.statusCode; } + + @Nullable @JsonIgnore + public UsergridClient getClient() { + return client; + } + @JsonIgnore public void setClient(@Nullable final UsergridClient client) { this.client = client; } + + @Nullable @JsonIgnore + public JsonNode getResponseJson() { + return responseJson; + } + private void setResponseJson(@Nullable final JsonNode responseJson) {this.responseJson = responseJson; } + + @Nullable @JsonIgnore + public UsergridQuery getQuery() { + return query; + } + private void setQuery(@Nullable final UsergridQuery query) { this.query = query; } + + @Nullable + public UsergridResponseError getResponseError() { + return responseError; + } + private void setResponseError(@Nullable final UsergridResponseError responseError) { this.responseError = responseError; } + + @Nullable + public Map<String, String> getHeaders() { + return headers; + } + private void setHeaders(@Nullable final Map<String, String> headers) { this.headers = headers; } + + @Nullable + public List<UsergridEntity> getEntities() { return entities; } + private void setEntities(@NotNull final List<UsergridEntity> entities) { this.entities = entities; } + + @Nullable @JsonProperty("cursor") + public String getCursor() { + return cursor; + } + @JsonProperty("cursor") + private void setCursor(@NotNull final String cursor) { this.cursor = cursor; } + + @Nullable @JsonProperty("access_token") + public String getAccessToken() { return this.accessToken; } + @JsonProperty("access_token") + private void setAccessToken(@NotNull final String accessToken) { this.accessToken = accessToken; } + + @Nullable @JsonProperty("expires_in") + public Long getExpires() { return this.expires; } + @JsonProperty("expires_in") + private void setExpires(@NotNull final Long expires) { this.expires = expires; } + + @JsonProperty("user") + private void setUser(@NotNull final UsergridUser user) { + if( this.entities == null ) { + this.entities = new ArrayList<>(); + } + this.entities.add(user); + } + + @NotNull @JsonAnyGetter + public Map<String, JsonNode> getProperties() { + return properties; + } + @JsonAnySetter + private void setProperty(@NotNull final String key, @NotNull final JsonNode value) { + properties.put(key, value); + } + + @NotNull + public UsergridResponse loadNextPage() { + UsergridClient client = this.client; + UsergridEntity entity = this.first(); + if( this.hasNextPage() && client != null && entity != null ) { + Map<String, Object> paramsMap = new HashMap<>(); + paramsMap.put("cursor", getCursor()); + UsergridRequest request = new UsergridRequest(UsergridEnums.UsergridHttpMethod.GET, UsergridRequest.APPLICATION_JSON_MEDIA_TYPE, client.clientAppUrl(), paramsMap, null, null, this.getQuery(), client.authForRequests() , entity.getType()); + return client.sendRequest(request); + } else { + return UsergridResponse.fromError(client,"Error Loading Next Page.","Unable to load next page."); + } + } + + @NotNull + public static UsergridResponse fromError(@Nullable final UsergridClient client, @NotNull final String errorName, @NotNull final String errorDescription) { + UsergridResponse response = new UsergridResponse(); + response.client = client; + response.responseError = new UsergridResponseError(errorName,errorDescription); + return response; + } + + @NotNull + public static UsergridResponse fromException(@Nullable final UsergridClient client, @NotNull final Exception ex) { + final UsergridResponse response = new UsergridResponse(); + response.client = client; + final UsergridResponseError responseError = new UsergridResponseError(); + responseError.setErrorDescription(ex.getMessage()); + if( ex.getClass() != null ) { + responseError.setErrorName(ex.getClass().toString()); + } + if( ex.getCause() != null ) { + responseError.setErrorException(ex.getCause().toString()); + } + response.responseError = responseError; + return response; + } + + @NotNull + public static UsergridResponse fromResponse(@NotNull final UsergridClient client, @NotNull final UsergridRequest request, @NotNull final okhttp3.Response requestResponse) { + UsergridResponse response; + JsonNode responseJson; + try { + String responseJsonString = requestResponse.body().string(); + responseJson = JsonUtils.mapper.readTree(responseJsonString); + } catch ( Exception e ) { + return UsergridResponse.fromException(client,e); + } + if ( responseJson.has("error") ) { + response = new UsergridResponse(); + response.responseError = JsonUtils.fromJsonNode(responseJson,UsergridResponseError.class); + } else { + response = JsonUtils.fromJsonNode(responseJson,UsergridResponse.class); + } + response.client = client; + response.responseJson = responseJson; + response.statusCode = requestResponse.code(); + + Headers responseHeaders = requestResponse.headers(); + HashMap<String,String> headers = new HashMap<>(); + for (int i = 0; i < responseHeaders.size(); i++) { + headers.put(responseHeaders.name(i),responseHeaders.value(i)); + } + + response.headers = headers; + response.query = request.getQuery(); + return response; + } +} http://git-wip-us.apache.org/repos/asf/usergrid-java/blob/88039bad/src/main/java/org/apache/usergrid/java/client/response/UsergridResponseError.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/usergrid/java/client/response/UsergridResponseError.java b/src/main/java/org/apache/usergrid/java/client/response/UsergridResponseError.java new file mode 100644 index 0000000..387ae56 --- /dev/null +++ b/src/main/java/org/apache/usergrid/java/client/response/UsergridResponseError.java @@ -0,0 +1,98 @@ +/* + * 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.java.client.response; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.JsonNode; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings("unused") +@JsonInclude(JsonInclude.Include.NON_NULL) +public class UsergridResponseError { + + @Nullable private String errorName; + @Nullable private String errorDescription; + @Nullable private String errorException; + + @NotNull private final Map<String, JsonNode> properties = new HashMap<>(); + + public UsergridResponseError() { + this(null,null,null); + } + public UsergridResponseError(@Nullable final String errorName) { + this(errorName, null, null); + } + public UsergridResponseError(@Nullable final String errorName, @Nullable final String errorDescription) { + this(errorName,errorDescription,null); + } + public UsergridResponseError(@Nullable final String errorName, @Nullable final String errorDescription, @Nullable final String errorException) { + this.errorName = errorName; + this.errorDescription = errorDescription; + this.errorException = errorException; + } + + @NotNull + @JsonAnyGetter + public Map<String, JsonNode> getProperties() { + return properties; + } + + @JsonAnySetter + public void setProperty(@NotNull final String key, @NotNull final JsonNode value) { + properties.put(key, value); + } + + @Nullable + @JsonProperty("error") + public String getErrorName() { + return errorName; + } + + @JsonProperty("error") + public void setErrorName(@NotNull final String errorName) { + this.errorName = errorName; + } + + @Nullable + @JsonProperty("exception") + public String getErrorException() { + return errorException; + } + + @JsonProperty("exception") + public void setErrorException(@NotNull final String errorException) { + this.errorException = errorException; + } + + @Nullable + @JsonProperty("error_description") + public String getErrorDescription() { + return errorDescription; + } + + @JsonProperty("error_description") + public void setErrorDescription(@NotNull final String errorDescription) { + this.errorDescription = errorDescription; + } +}