mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Transfer Service:
- Rehydration of exception received from target repo git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@22413 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -35,6 +35,8 @@ import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.transfer.TransferException;
|
||||
import org.alfresco.service.cmr.transfer.TransferProgress;
|
||||
import org.alfresco.service.cmr.transfer.TransferTarget;
|
||||
import org.alfresco.util.json.ExceptionJsonSerializer;
|
||||
import org.alfresco.util.json.JsonSerializer;
|
||||
import org.apache.commons.httpclient.HostConfiguration;
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
import org.apache.commons.httpclient.HttpMethod;
|
||||
@@ -54,6 +56,7 @@ import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
/**
|
||||
@@ -80,6 +83,8 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
private Protocol httpProtocol = new Protocol(HTTP_SCHEME_NAME, new DefaultProtocolSocketFactory(), DEFAULT_HTTP_PORT);
|
||||
private Protocol httpsProtocol = new Protocol(HTTPS_SCHEME_NAME, (ProtocolSocketFactory) new SSLProtocolSocketFactory(), DEFAULT_HTTPS_PORT);
|
||||
private Map<String,Protocol> protocolMap = null;
|
||||
private HttpMethodFactory httpMethodFactory = null;
|
||||
private JsonSerializer<Throwable, JSONObject> jsonErrorSerializer;
|
||||
|
||||
private ContentService contentService;
|
||||
|
||||
@@ -91,6 +96,8 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
|
||||
httpClient = new HttpClient();
|
||||
httpClient.setHttpConnectionManager(new MultiThreadedHttpConnectionManager());
|
||||
httpMethodFactory = new StandardHttpMethodFactoryImpl();
|
||||
jsonErrorSerializer = new ExceptionJsonSerializer();
|
||||
}
|
||||
|
||||
public void init()
|
||||
@@ -123,7 +130,7 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
*/
|
||||
public void verifyTarget(TransferTarget target) throws TransferException
|
||||
{
|
||||
HttpMethod verifyRequest = new PostMethod();
|
||||
HttpMethod verifyRequest = getPostMethod();
|
||||
try
|
||||
{
|
||||
HostConfiguration hostConfig = getHostConfig(target);
|
||||
@@ -165,8 +172,8 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
log.error("Received \"unsuccessful\" response code from target server: " + response);
|
||||
String errorPayload = method.getResponseBodyAsString();
|
||||
JSONObject errorObj = new JSONObject(errorPayload);
|
||||
errorId = errorObj.getString("errorId");
|
||||
JSONArray errorParamArray = errorObj.getJSONArray("errorParams");
|
||||
errorId = errorObj.getString("alfrescoErrorId");
|
||||
JSONArray errorParamArray = errorObj.getJSONArray("alfrescoErrorParams");
|
||||
int length = errorParamArray.length();
|
||||
errorParams = new String[length];
|
||||
for (int i = 0; i < length; ++i)
|
||||
@@ -185,7 +192,7 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
private HttpState getHttpState(TransferTarget target)
|
||||
protected HttpState getHttpState(TransferTarget target)
|
||||
{
|
||||
HttpState httpState = new HttpState();
|
||||
httpState.setCredentials(new AuthScope(target.getEndpointHost(), target.getEndpointPort(),
|
||||
@@ -219,7 +226,7 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
|
||||
public Transfer begin(TransferTarget target) throws TransferException
|
||||
{
|
||||
HttpMethod beginRequest = new PostMethod();
|
||||
HttpMethod beginRequest = getPostMethod();
|
||||
try
|
||||
{
|
||||
HostConfiguration hostConfig = getHostConfig(target);
|
||||
@@ -263,7 +270,7 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
public void sendManifest(Transfer transfer, File manifest, OutputStream result) throws TransferException
|
||||
{
|
||||
TransferTarget target = transfer.getTransferTarget();
|
||||
PostMethod postSnapshotRequest = new PostMethod();
|
||||
PostMethod postSnapshotRequest = getPostMethod();
|
||||
MultipartRequestEntity requestEntity;
|
||||
|
||||
if(log.isDebugEnabled())
|
||||
@@ -332,7 +339,7 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
public void abort(Transfer transfer) throws TransferException
|
||||
{
|
||||
TransferTarget target = transfer.getTransferTarget();
|
||||
HttpMethod abortRequest = new PostMethod();
|
||||
HttpMethod abortRequest = getPostMethod();
|
||||
try
|
||||
{
|
||||
HostConfiguration hostConfig = getHostConfig(target);
|
||||
@@ -370,7 +377,7 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
public void commit(Transfer transfer) throws TransferException
|
||||
{
|
||||
TransferTarget target = transfer.getTransferTarget();
|
||||
HttpMethod commitRequest = new PostMethod();
|
||||
HttpMethod commitRequest = getPostMethod();
|
||||
try
|
||||
{
|
||||
HostConfiguration hostConfig = getHostConfig(target);
|
||||
@@ -407,7 +414,7 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
public void prepare(Transfer transfer) throws TransferException
|
||||
{
|
||||
TransferTarget target = transfer.getTransferTarget();
|
||||
HttpMethod prepareRequest = new PostMethod();
|
||||
HttpMethod prepareRequest = getPostMethod();
|
||||
try
|
||||
{
|
||||
HostConfiguration hostConfig = getHostConfig(target);
|
||||
@@ -452,7 +459,7 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
}
|
||||
|
||||
TransferTarget target = transfer.getTransferTarget();
|
||||
PostMethod postContentRequest = new PostMethod();
|
||||
PostMethod postContentRequest = getPostMethod();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -517,7 +524,7 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
public TransferProgress getStatus(Transfer transfer) throws TransferException
|
||||
{
|
||||
TransferTarget target = transfer.getTransferTarget();
|
||||
HttpMethod statusRequest = new PostMethod();
|
||||
HttpMethod statusRequest = getPostMethod();
|
||||
try
|
||||
{
|
||||
HostConfiguration hostConfig = getHostConfig(target);
|
||||
@@ -539,11 +546,15 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
int currentPosition = statusObj.getInt("currentPosition");
|
||||
int endPosition = statusObj.getInt("endPosition");
|
||||
String statusStr= statusObj.getString("status");
|
||||
//We're expecting the transfer progress encoded in a JSON object...
|
||||
|
||||
JSONObject errorJSON = statusObj.getJSONObject("error");
|
||||
Throwable throwable = rehydrateError(errorJSON);
|
||||
|
||||
TransferProgress p = new TransferProgress();
|
||||
p.setStatus(TransferProgress.Status.valueOf(statusStr));
|
||||
p.setCurrentPosition(currentPosition);
|
||||
p.setEndPosition(endPosition);
|
||||
p.setError(throwable);
|
||||
return p;
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
@@ -569,9 +580,7 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
public void getTransferReport(Transfer transfer, OutputStream result)
|
||||
{
|
||||
TransferTarget target = transfer.getTransferTarget();
|
||||
PostMethod getReportRequest = new PostMethod();
|
||||
MultipartRequestEntity requestEntity;
|
||||
|
||||
PostMethod getReportRequest = getPostMethod();
|
||||
try
|
||||
{
|
||||
HostConfiguration hostConfig = getHostConfig(target);
|
||||
@@ -622,6 +631,24 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
}
|
||||
}
|
||||
|
||||
protected PostMethod getPostMethod()
|
||||
{
|
||||
return httpMethodFactory.createPostMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param errorJSON A JSON object expected to hold the name of the error class ("errorType"),
|
||||
* the error message ("errorMessage"), and, optionally, the Alfresco message id ("alfrescoErrorId")
|
||||
* and Alfresco message parameters ("alfrescoErrorParams").
|
||||
* @return The rehydrated error object, or null if errorJSON is null.
|
||||
* @throws JSONException if an error occurs while parsing the supplied JSON object
|
||||
*/
|
||||
private Throwable rehydrateError(JSONObject errorJSON)
|
||||
{
|
||||
return jsonErrorSerializer.deserialize(errorJSON);
|
||||
}
|
||||
|
||||
public void setContentService(ContentService contentService)
|
||||
{
|
||||
this.contentService = contentService;
|
||||
@@ -631,4 +658,15 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
|
||||
{
|
||||
return contentService;
|
||||
}
|
||||
} // end of class
|
||||
|
||||
public void setHttpMethodFactory(HttpMethodFactory httpMethodFactory)
|
||||
{
|
||||
this.httpMethodFactory = httpMethodFactory;
|
||||
}
|
||||
|
||||
public void setJsonErrorSerializer(JsonSerializer<Throwable, JSONObject> jsonErrorSerializer)
|
||||
{
|
||||
this.jsonErrorSerializer = jsonErrorSerializer;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -18,16 +18,21 @@
|
||||
*/
|
||||
package org.alfresco.repo.transfer;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.service.cmr.transfer.TransferException;
|
||||
import org.alfresco.service.cmr.transfer.TransferProgress;
|
||||
import org.alfresco.service.cmr.transfer.TransferProgress.Status;
|
||||
import org.alfresco.util.json.ExceptionJsonSerializer;
|
||||
import org.apache.commons.httpclient.ConnectTimeoutException;
|
||||
import org.apache.commons.httpclient.HostConfiguration;
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
@@ -36,7 +41,10 @@ import org.apache.commons.httpclient.HttpState;
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
import org.apache.commons.httpclient.params.HttpConnectionParams;
|
||||
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
|
||||
import org.json.JSONObject;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
/**
|
||||
* Unit test for HttpClientTransmitterImpl
|
||||
@@ -59,6 +67,7 @@ public class HttpClientTransmitterImplTest extends TestCase
|
||||
private HttpClientTransmitterImpl transmitter;
|
||||
private HttpClient mockedHttpClient;
|
||||
private TransferTargetImpl target;
|
||||
private MockableHttpMethodFactory mockedHttpMethodFactory;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see junit.framework.TestCase#setUp()
|
||||
@@ -70,7 +79,9 @@ public class HttpClientTransmitterImplTest extends TestCase
|
||||
|
||||
this.transmitter = new HttpClientTransmitterImpl();
|
||||
this.mockedHttpClient = mock(HttpClient.class);
|
||||
this.mockedHttpMethodFactory = new MockableHttpMethodFactory();
|
||||
transmitter.setHttpClient(mockedHttpClient);
|
||||
transmitter.setHttpMethodFactory(mockedHttpMethodFactory);
|
||||
|
||||
this.target = new TransferTargetImpl();
|
||||
target.setEndpointHost(TARGET_HOST);
|
||||
@@ -195,6 +206,38 @@ public class HttpClientTransmitterImplTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetStatusErrorRehydration() throws Exception
|
||||
{
|
||||
final ExceptionJsonSerializer errorSerializer = new ExceptionJsonSerializer();
|
||||
final TransferException expectedException = new TransferException("my message id", new Object[] {"param1", "param2"});
|
||||
when(mockedHttpClient.executeMethod(any(HostConfiguration.class), any(HttpMethod.class),
|
||||
any(HttpState.class))).thenReturn(200);
|
||||
doAnswer(new Answer<String>() {
|
||||
@Override
|
||||
public String answer(InvocationOnMock invocation) throws Throwable
|
||||
{
|
||||
JSONObject progressObject = new JSONObject();
|
||||
progressObject.put("transferId", "mytransferid");
|
||||
progressObject.put("status", Status.ERROR);
|
||||
progressObject.put("currentPosition", 1);
|
||||
progressObject.put("endPosition", 10);
|
||||
JSONObject errorObject = errorSerializer.serialize(expectedException);
|
||||
progressObject.put("error", errorObject);
|
||||
return progressObject.toString();
|
||||
}
|
||||
}).when(mockedHttpMethodFactory.latestPostMethod).getResponseBodyAsString();
|
||||
|
||||
Transfer transfer = new Transfer();
|
||||
transfer.setTransferId("mytransferid");
|
||||
transfer.setTransferTarget(target);
|
||||
TransferProgress progress = transmitter.getStatus(transfer);
|
||||
assertTrue(progress.getError() != null);
|
||||
assertEquals(expectedException.getClass(), progress.getError().getClass());
|
||||
TransferException receivedException = (TransferException)progress.getError();
|
||||
assertEquals(expectedException.getMsgId(), receivedException.getMsgId());
|
||||
assertTrue(Arrays.deepEquals(expectedException.getMsgParams(), receivedException.getMsgParams()));
|
||||
}
|
||||
|
||||
private static class CustomSocketFactory implements SecureProtocolSocketFactory
|
||||
{
|
||||
|
||||
@@ -236,6 +279,26 @@ public class HttpClientTransmitterImplTest extends TestCase
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MockableHttpMethodFactory implements HttpMethodFactory
|
||||
{
|
||||
private PostMethod latestPostMethod;
|
||||
|
||||
public MockableHttpMethodFactory()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PostMethod createPostMethod()
|
||||
{
|
||||
return latestPostMethod;
|
||||
}
|
||||
|
||||
public void reset()
|
||||
{
|
||||
latestPostMethod = spy(new PostMethod());;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.transfer;
|
||||
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
|
||||
public interface HttpMethodFactory
|
||||
{
|
||||
PostMethod createPostMethod();
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.transfer;
|
||||
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
|
||||
public class StandardHttpMethodFactoryImpl implements HttpMethodFactory
|
||||
{
|
||||
|
||||
@Override
|
||||
public PostMethod createPostMethod()
|
||||
{
|
||||
return new PostMethod();
|
||||
}
|
||||
|
||||
}
|
@@ -58,6 +58,7 @@ import org.alfresco.service.cmr.transfer.TransferEventSendingContent;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventSendingSnapshot;
|
||||
import org.alfresco.service.cmr.transfer.TransferEventSuccess;
|
||||
import org.alfresco.service.cmr.transfer.TransferException;
|
||||
import org.alfresco.service.cmr.transfer.TransferFailureException;
|
||||
import org.alfresco.service.cmr.transfer.TransferProgress;
|
||||
import org.alfresco.service.cmr.transfer.TransferService2;
|
||||
import org.alfresco.service.cmr.transfer.TransferTarget;
|
||||
@@ -293,7 +294,7 @@ public class TransferServiceCallbackTest extends TestCase
|
||||
verifyCallback(expectedEvents);
|
||||
}
|
||||
|
||||
public void xtestErrorDuringCommit()
|
||||
public void testErrorDuringCommit()
|
||||
{
|
||||
Exception error = new TransferException("Commit failed");
|
||||
|
||||
@@ -329,8 +330,13 @@ public class TransferServiceCallbackTest extends TestCase
|
||||
|
||||
TransferDefinition transferDef = new TransferDefinition();
|
||||
transferDef.setNodes(folder1, file1, file2, file3);
|
||||
try
|
||||
{
|
||||
transferService.transfer(TRANSFER_TARGET_NAME, transferDef, mockedCallback);
|
||||
|
||||
fail();
|
||||
}
|
||||
catch (TransferFailureException ex)
|
||||
{
|
||||
List<TransferEvent> expectedEvents = new ArrayList<TransferEvent>();
|
||||
TransferEventImpl event;
|
||||
|
||||
@@ -406,6 +412,14 @@ public class TransferServiceCallbackTest extends TestCase
|
||||
event.setTransferState(TransferState.COMMITTING);
|
||||
expectedEvents.add(event);
|
||||
|
||||
event = new TransferEventReport();
|
||||
event.setTransferState(TransferState.COMMITTING);
|
||||
expectedEvents.add(event);
|
||||
|
||||
event = new TransferEventReport();
|
||||
event.setTransferState(TransferState.COMMITTING);
|
||||
expectedEvents.add(event);
|
||||
|
||||
event = new TransferEventEndState();
|
||||
event.setTransferState(TransferState.COMMITTING);
|
||||
expectedEvents.add(event);
|
||||
@@ -419,14 +433,9 @@ public class TransferServiceCallbackTest extends TestCase
|
||||
((TransferEventError)event).setException(error);
|
||||
expectedEvents.add(event);
|
||||
|
||||
event = new TransferEventReport();
|
||||
expectedEvents.add(event);
|
||||
|
||||
event = new TransferEventReport();
|
||||
expectedEvents.add(event);
|
||||
|
||||
verifyCallback(expectedEvents);
|
||||
}
|
||||
}
|
||||
|
||||
public void testTargetAlreadyLocked()
|
||||
{
|
||||
@@ -440,7 +449,7 @@ public class TransferServiceCallbackTest extends TestCase
|
||||
transferService.transfer(TRANSFER_TARGET_NAME, transferDef, mockedCallback);
|
||||
fail("Transfer expected to throw an exception, but it didn't.");
|
||||
}
|
||||
catch(TransferException ex)
|
||||
catch(TransferFailureException ex)
|
||||
{
|
||||
List<TransferEvent> expectedEvents = new ArrayList<TransferEvent>();
|
||||
TransferEventImpl event;
|
||||
@@ -467,7 +476,7 @@ public class TransferServiceCallbackTest extends TestCase
|
||||
|
||||
event = new TransferEventError();
|
||||
event.setTransferState(TransferState.ERROR);
|
||||
((TransferEventError)event).setException(ex);
|
||||
((TransferEventError)event).setException((Exception)ex.getCause());
|
||||
expectedEvents.add(event);
|
||||
|
||||
verifyCallback(expectedEvents);
|
||||
|
@@ -674,7 +674,14 @@ public class TransferServiceImpl2 implements TransferService2
|
||||
{
|
||||
targetError = new TransferException(MSG_UNKNOWN_TARGET_ERROR);
|
||||
}
|
||||
if (Exception.class.isAssignableFrom(targetError.getClass()))
|
||||
{
|
||||
failureException = (Exception)targetError;
|
||||
}
|
||||
else
|
||||
{
|
||||
failureException = new TransferException(MSG_TARGET_ERROR, new Object[] {targetError.getMessage()}, targetError);
|
||||
}
|
||||
clientState = ClientTransferState.Finished;
|
||||
break;
|
||||
}
|
||||
|
170
source/java/org/alfresco/util/json/ExceptionJsonSerializer.java
Normal file
170
source/java/org/alfresco/util/json/ExceptionJsonSerializer.java
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.util.json;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.cmr.transfer.TransferException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class ExceptionJsonSerializer implements JsonSerializer<Throwable, JSONObject>
|
||||
{
|
||||
private final static Log log = LogFactory.getLog(ExceptionJsonSerializer.class);
|
||||
|
||||
@Override
|
||||
public Throwable deserialize(JSONObject errorJSON)
|
||||
{
|
||||
if (errorJSON == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Throwable result = null;
|
||||
Object createdObject = null;
|
||||
|
||||
try
|
||||
{
|
||||
//errorType and errorMessage should always be reported
|
||||
String errorType = errorJSON.getString("errorType");
|
||||
String errorMessage = errorJSON.getString("errorMessage");
|
||||
|
||||
if (errorType == null)
|
||||
{
|
||||
errorType = Exception.class.getName();
|
||||
}
|
||||
if (errorMessage == null)
|
||||
{
|
||||
errorMessage = "";
|
||||
}
|
||||
//alfrescoErrorId and alfrescoErrorParams will only appear if the
|
||||
//throwable object was of a subclass of AlfrescoRuntimeException
|
||||
String errorId = errorJSON.optString("alfrescoMessageId", null);
|
||||
Object[] errorParams = new Object[0];
|
||||
JSONArray errorParamArray = errorJSON.optJSONArray("alfrescoMessageParams");
|
||||
if (errorParamArray != null)
|
||||
{
|
||||
int length = errorParamArray.length();
|
||||
errorParams = new Object[length];
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
errorParams[i] = errorParamArray.getString(i);
|
||||
}
|
||||
}
|
||||
Class<?> errorClass;
|
||||
try
|
||||
{
|
||||
errorClass = Class.forName(errorType);
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
errorClass = Exception.class;
|
||||
}
|
||||
Constructor<?> constructor = null;
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
constructor = errorClass.getConstructor(String.class, Object[].class);
|
||||
createdObject = constructor.newInstance(errorId, errorParams);
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
try
|
||||
{
|
||||
constructor = errorClass.getConstructor(String.class);
|
||||
createdObject = constructor.newInstance(errorId == null ? errorMessage : errorId);
|
||||
}
|
||||
catch (NoSuchMethodException e1)
|
||||
{
|
||||
try
|
||||
{
|
||||
constructor = errorClass.getConstructor();
|
||||
createdObject = constructor.newInstance();
|
||||
}
|
||||
catch (NoSuchMethodException e2)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
//We don't need to do anything here. Code below will fix things up
|
||||
}
|
||||
if (createdObject == null || !Throwable.class.isAssignableFrom(createdObject.getClass()))
|
||||
{
|
||||
result = new TransferException(errorId == null ? errorMessage : errorId, errorParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (Throwable)createdObject;
|
||||
}
|
||||
}
|
||||
catch(JSONException ex)
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Failed to deserialize Throwable object from JSON object", ex);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject serialize(Throwable object)
|
||||
{
|
||||
JSONObject errorObject = new JSONObject();
|
||||
|
||||
try
|
||||
{
|
||||
errorObject.put("errorType", object.getClass().getName());
|
||||
errorObject.put("errorMessage", object.getMessage());
|
||||
if (AlfrescoRuntimeException.class.isAssignableFrom(object.getClass()))
|
||||
{
|
||||
AlfrescoRuntimeException alfEx = (AlfrescoRuntimeException)object;
|
||||
errorObject.put("alfrescoMessageId", alfEx.getMsgId());
|
||||
Object[] msgParams = alfEx.getMsgParams();
|
||||
List<Object> params = msgParams == null ? Collections.emptyList() : Arrays.asList(msgParams);
|
||||
errorObject.put("alfrescoMessageParams", params);
|
||||
}
|
||||
}
|
||||
catch (JSONException e)
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Failed to serialize Throwable object into JSON object", e);
|
||||
}
|
||||
}
|
||||
return errorObject;
|
||||
}
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.util.json;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
|
||||
public class ExceptionJsonSerializerTest extends TestCase
|
||||
{
|
||||
|
||||
private ExceptionJsonSerializer serializer;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
serializer = new ExceptionJsonSerializer();
|
||||
}
|
||||
|
||||
public void testIllegalArgumentException()
|
||||
{
|
||||
Exception expectedException = new IllegalArgumentException("This is the message");
|
||||
JSONObject obj = serializer.serialize(expectedException);
|
||||
Throwable actualException = serializer.deserialize(obj);
|
||||
assertEquals(expectedException.getClass(), actualException.getClass());
|
||||
assertEquals(expectedException.getMessage(), actualException.getMessage());
|
||||
}
|
||||
|
||||
public void testAlfrescoRuntimeExceptionWithNoParams()
|
||||
{
|
||||
AlfrescoRuntimeException expectedException = new AlfrescoRuntimeException("message id");
|
||||
JSONObject obj = serializer.serialize(expectedException);
|
||||
Throwable actualException = serializer.deserialize(obj);
|
||||
assertEquals(expectedException.getClass(), actualException.getClass());
|
||||
assertEquals(expectedException.getMsgId(), ((AlfrescoRuntimeException)actualException).getMsgId());
|
||||
assertTrue(((AlfrescoRuntimeException)actualException).getMsgParams().length == 0);
|
||||
}
|
||||
|
||||
public void testAlfrescoRuntimeExceptionWithParams()
|
||||
{
|
||||
AlfrescoRuntimeException expectedException = new AlfrescoRuntimeException("message id",
|
||||
new Object[]{"one","two","three"});
|
||||
JSONObject obj = serializer.serialize(expectedException);
|
||||
Throwable actualException = serializer.deserialize(obj);
|
||||
assertEquals(expectedException.getClass(), actualException.getClass());
|
||||
assertEquals(expectedException.getMsgId(), ((AlfrescoRuntimeException)actualException).getMsgId());
|
||||
assertTrue(Arrays.deepEquals(expectedException.getMsgParams(),
|
||||
((AlfrescoRuntimeException)actualException).getMsgParams()));
|
||||
}
|
||||
|
||||
public void testAccessDeniedException()
|
||||
{
|
||||
AccessDeniedException expectedException = new AccessDeniedException("message id");
|
||||
JSONObject obj = serializer.serialize(expectedException);
|
||||
Throwable actualException = serializer.deserialize(obj);
|
||||
assertEquals(expectedException.getClass(), actualException.getClass());
|
||||
assertEquals(expectedException.getMsgId(), ((AlfrescoRuntimeException)actualException).getMsgId());
|
||||
assertTrue(expectedException.getMsgParams() == null);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user