/* See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* Esri Inc. 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 com.esri.gpt.catalog.arcgis.agportal.publication;
import com.esri.gpt.catalog.arcgis.agportal.itemInfo.ESRI_ItemInformation;
import com.esri.gpt.framework.collection.StringAttributeMap;
import com.esri.gpt.framework.context.ApplicationContext;
import com.esri.gpt.framework.context.RequestContext;
import com.esri.gpt.framework.geometry.Envelope;
import com.esri.gpt.framework.http.CredentialProvider;
import com.esri.gpt.framework.http.HttpClientRequest;
import com.esri.gpt.framework.http.HttpClientRequest.MethodName;
import com.esri.gpt.framework.http.StringProvider;
import com.esri.gpt.framework.util.Val;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.json.JSONException;
import org.json.JSONObject;
/**
* This class is used to handle publication request to ArcGIS Portal instance.
* NOTE! This is EXPERIMENTAL feature. It might be removed at any time in the future.
* @deprecated
*/
@Deprecated
public class PublicationRequest {
/**
* instance variables
* =========================================================
*/
private CredentialProvider credentialProvider = null;
private RequestContext requestContext = null;
private EndPoint ep;
private String addItemUrl = null;
private String shareItemUrl = null;
private String token = null;
private String referer = null;
private String itemId = null;
private boolean publicationStatus = false;
/** The logger. */
private static final Logger LOGGER = Logger.getLogger(PublicationRequest.class.getName());
/**
* Creates instance of the request.
* @param requestContext context
* @param endPoint end-point
* @param credtialProvider credential provider
* @param httpReferer referer
* @throws Exception if publication fails
*/
public PublicationRequest(RequestContext requestContext, EndPoint endPoint, CredentialProvider credtialProvider, String httpReferer) throws Exception {
if (credtialProvider == null) {
throw new IllegalArgumentException("Null credentials provided.");
}
if (requestContext == null) {
throw new IllegalArgumentException(" Null request context provided.");
}
if (Val.chkStr(httpReferer).length() == 0) {
throw new IllegalArgumentException("Null http referer provided.");
}
this.credentialProvider = credtialProvider;
this.requestContext = requestContext;
this.ep = endPoint;
this.addItemUrl = this.ep.getBaseArcGISUrl() + "content/users/{0}/addItem";
this.shareItemUrl = this.ep.getBaseArcGISUrl() + "content/users/{0}/shareItems";
this.referer = httpReferer;
}
/**
* Constructs a request to publish an itemInfo to ArcGIS Portal instance.
*
* @param requestContext
* the request context
* @param credtialProvider
* the CredentialProvider
* @param httpReferer
* the Http Referer
* @throws Exception
*/
public PublicationRequest(RequestContext requestContext,
CredentialProvider credtialProvider, String httpReferer) throws Exception {
this(requestContext, EndPoint.extract(requestContext), credtialProvider, httpReferer);
}
/**
* methods =================================================================
*/
private boolean hasMetadataViewTag(String str) {
Pattern p = Pattern.compile("\\>Metadata\\</[aA]\\>[ \t\r\n]*$");
return p.matcher(str).find();
}
private String makeMetadataViewTag(String id) {
String viewUrl = makeMetadataViewUrl(id);
if (viewUrl.length()>0) {
return "</br><a href='"+viewUrl+"' target='_blank'>Metadata</a>";
}
return "";
}
private String makeMetadataViewUrl(String id) {
StringAttributeMap params = ApplicationContext.getInstance().getConfiguration().getCatalogConfiguration().getParameters();
String basePath = Val.chkStr(params.getValue("reverseProxy.baseContextPath"));
if (basePath.length()>0) {
return basePath + "/catalog/search/resource/details.page?uuid=" + formatUuid(id);
}
return "";
}
private String formatUuid(String uuid) {
uuid = Val.chkStr(uuid);
String value = uuid.replaceAll("[^0-9a-fA-F]", "");
if (value.length()==32) {
StringBuilder sb = new StringBuilder();
sb.append(value.substring(0, 8));
sb.append("-");
sb.append(value.substring(8, 12));
sb.append("-");
sb.append(value.substring(12, 16));
sb.append("-");
sb.append(value.substring(16, 20));
sb.append("-");
sb.append(value.substring(20));
value = "{"+sb.toString()+"}";
} else {
value = uuid;
}
return value;
}
/**
* Adds item to ArcGIS Portal instance.
*
* @param itemInfo
* the ESRI_ItemInformation object to be published.
* @throws IOException
* @throws JSONException
*/
private void addItem(ESRI_ItemInformation itemInfo) throws IOException, JSONException {
String content = "";
this.publicationStatus = false;
if (this.token != null && this.token.length() > 0) {
this.addItemUrl = this.addItemUrl.replace("{0}",
this.credentialProvider.getUsername());
content = "f=json&overwrite=" + "true" + "&token="
+ URLEncoder.encode(this.token, "UTF-8");
// file
content += "&URL="
+ URLEncoder.encode(itemInfo.getUrl(), "UTF-8");
content += "&title=" + URLEncoder.encode(itemInfo.getTitle(), "UTF-8");
content += "&type=" + URLEncoder.encode(itemInfo.getType(), "UTF-8");
content += "&tags=" + URLEncoder.encode(itemInfo.getTagsAsString(), "UTF-8");
if (itemInfo.getTags().isEmpty()) {
if (itemInfo.getDescription().length() > 0) {
content += "&tags=" + URLEncoder.encode(itemInfo.getDescription(), "UTF-8");
} else if (itemInfo.getTitle().length() > 0) {
content += "&tags=" + URLEncoder.encode(itemInfo.getTitle(), "UTF-8");
}
}
if (itemInfo.getName().length() > 0) {
content += "&name=" + URLEncoder.encode(itemInfo.getName(), "UTF-8");
}
if (itemInfo.getDescription().length() > 0) {
String viewTag = !hasMetadataViewTag(itemInfo.getDescription())? makeMetadataViewTag(itemInfo.getId()): "";
content += "&description="
+ URLEncoder.encode(itemInfo.getDescription()+viewTag, "UTF-8");
} else {
content += "&description="+URLEncoder.encode(makeMetadataViewTag(itemInfo.getId()),"UTF-8");
}
if (itemInfo.getThumbnailUrl().length() > 0) {
content += "&thumbnailurl="
+ URLEncoder.encode(itemInfo.getThumbnailUrl(), "UTF-8");
}
Envelope extent = itemInfo.getExtent();
if (extent != null && !extent.isEmpty()) {
content += "&extent=" + extent.getMinX() + "," + extent.getMinY() + ","
+ extent.getMaxX() + "," + extent.getMaxY();
}
HttpClientRequest httpClient = new HttpClientRequest();
httpClient.setContentProvider(new StringProvider(content,
"application/x-www-form-urlencoded"));
httpClient.setUrl(this.addItemUrl);
httpClient.setRequestHeader("Referer", this.referer);
httpClient.setMethodName(MethodName.POST);
httpClient.execute();
int nHttpResponseCode = httpClient.getResponseInfo().getResponseCode();
if ((nHttpResponseCode < 200) || (nHttpResponseCode > 299)) {
throw new JSONException("Add item request failed: HTTP "
+ nHttpResponseCode);
}
String resp = httpClient.readResponseAsCharacters();
if (resp.length() > 0) {
JSONObject jsoResponse;
try {
jsoResponse = new JSONObject(resp);
} catch (JSONException e) {
throw new JSONException(
"Error occurred while trying publish item, cause :"
+ e.getMessage());
}
if (jsoResponse.has("id") && jsoResponse.has("success")
&& jsoResponse.getString("success").equalsIgnoreCase("true")) {
this.itemId = jsoResponse.getString("id");
this.publicationStatus = true;
}
}
}
}
/**
* Fetch ArcGIS portal token.
* @throws IOException
* @throws JSONException
*/
private void fetchToken() throws IOException, JSONException {
String content = "";
this.publicationStatus = false;
content = URLEncoder.encode("f", "UTF-8") + "="
+ URLEncoder.encode("json", "UTF-8") + "&"
+ URLEncoder.encode("username", "UTF-8") + "="
+ URLEncoder.encode(this.credentialProvider.getUsername(), "UTF-8")
+ "&" + URLEncoder.encode("password", "UTF-8") + "="
+ URLEncoder.encode(this.credentialProvider.getPassword(), "UTF-8");
HttpClientRequest httpClient = new HttpClientRequest();
// send the request
content += "&expiration=525600&referer=" + this.referer;
httpClient.setContentProvider(new StringProvider(content,
"application/x-www-form-urlencoded"));
httpClient.setRequestHeader("Referer", this.referer);
httpClient.setUrl(this.ep.getGenerateTokenUrl());
httpClient.setMethodName(MethodName.POST);
// expiration
httpClient.execute();
int nHttpResponseCode = httpClient.getResponseInfo().getResponseCode();
if ((nHttpResponseCode < 200) || (nHttpResponseCode > 299)) {
throw new IOException("Request failed: HTTP " + nHttpResponseCode);
}
String resp = httpClient.readResponseAsCharacters();
JSONObject jsoToken = new JSONObject(resp);
if (jsoToken.has("token")) {
this.token = jsoToken.getString("token");
this.publicationStatus = true;
} else {
throw new IOException("Failed to generate token");
}
}
/**
* Processes the ArcGIS Portal publication request.
*
* @param itemInfo
* the ESRI_ItemInformation object.
* @throws Exception
* @throws IOException
* @throws JSONException
*/
public boolean publish(ESRI_ItemInformation itemInfo) throws IOException, JSONException, Exception {
this.publicationStatus = false;
try {
if (itemInfo == null) {
throw new Exception("ItemInfo is null.");
} else {
fetchToken();
if (this.publicationStatus) {
addItem(itemInfo);
if (this.publicationStatus) {
shareItem(itemInfo);
}
}
}
} finally {
if (this.requestContext != null) {
this.requestContext.onExecutionPhaseCompleted();
}
}
return this.publicationStatus;
}
/**
* Sets access right in ArcGIS Portal for item.
*
* @param itemInfo
* @throws Exception
*/
private void shareItem(ESRI_ItemInformation itemInfo) throws Exception {
String content = "";
this.publicationStatus = false;
if (this.token != null && this.token.length() > 0) {
if (itemId != null && itemId.length() > 0) {
this.shareItemUrl = shareItemUrl.replace("{0}",
this.credentialProvider.getUsername());
content = "f=json&token=" + URLEncoder.encode(this.token, "UTF-8");
content += "&everyone=true&items=" + this.itemId;
HttpClientRequest httpClient = new HttpClientRequest();
httpClient.setContentProvider(new StringProvider(content,
"application/x-www-form-urlencoded"));
httpClient.setRequestHeader("Referer", this.referer);
httpClient.setUrl(this.shareItemUrl);
httpClient.setMethodName(MethodName.POST);
httpClient.execute();
int nHttpResponseCode = httpClient.getResponseInfo().getResponseCode();
if ((nHttpResponseCode < 200) || (nHttpResponseCode > 299)) {
LOGGER.info("Share item request failed: HTTP " + nHttpResponseCode);
} else {
this.publicationStatus = true;
LOGGER.info("Item shared with everyone." + nHttpResponseCode);
}
}
}
}
}