You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ka...@apache.org on 2013/10/27 11:50:24 UTC

svn commit: r1536087 - in /directory/escimo/trunk: client/ client/src/main/java/org/apache/directory/scim/ common/src/main/java/org/apache/directory/scim/ common/src/main/java/org/apache/directory/scim/json/ ldap/src/main/java/org/apache/directory/scim...

Author: kayyagari
Date: Sun Oct 27 10:50:23 2013
New Revision: 1536087

URL: http://svn.apache.org/r1536087
Log:
handling error conditions as per the specification

Added:
    directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoResult.java
    directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ResourceConflictException.java
    directory/escimo/trunk/schema/src/main/java/org/apache/directory/scim/schema/ErrorCode.java
    directory/escimo/trunk/schema/src/main/java/org/apache/directory/scim/schema/ErrorResponse.java
Modified:
    directory/escimo/trunk/client/pom.xml
    directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoClient.java
    directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeHandler.java
    directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeNotFoundException.java
    directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ResourceNotFoundException.java
    directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ScimUtil.java
    directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/json/ResourceSerializer.java
    directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapResourceProvider.java
    directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/ActiveAttributeHandler.java
    directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/GroupsAttributeHandler.java
    directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MembersAttributeHandler.java
    directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MetaAttributeHandler.java
    directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/PhotosAttributeHandler.java
    directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/UserService.java
    directory/escimo/trunk/tests/src/test/java/org/apache/directory/scim/UserResourceTest.java

Modified: directory/escimo/trunk/client/pom.xml
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/client/pom.xml?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/client/pom.xml (original)
+++ directory/escimo/trunk/client/pom.xml Sun Oct 27 10:50:23 2013
@@ -40,12 +40,6 @@
      <version>${httpclient.version}</version>
    </dependency>
 
-   <dependency>
-     <groupId>${project.groupId}</groupId>
-     <artifactId>escimo-common</artifactId>
-     <version>${project.version}</version>
-   </dependency>   
-      
   </dependencies>
 
 </project>

Modified: directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoClient.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoClient.java?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoClient.java (original)
+++ directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoClient.java Sun Oct 27 10:50:23 2013
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.directory.scim.schema.CoreResource;
+import org.apache.directory.scim.schema.ErrorResponse;
 import org.apache.http.HttpResponse;
 import org.apache.http.StatusLine;
 import org.apache.http.client.HttpClient;
@@ -80,63 +81,63 @@ public class EscimoClient
         serializer = gb.create();
     }
 
-    public CoreResource addUser( CoreResource resource ) throws Exception
+    public EscimoResult addUser( CoreResource resource )
     {
         return addResource( resource, USERS_URI );
     }
 
     
-    public CoreResource addGroup( CoreResource resource ) throws Exception
+    public EscimoResult addGroup( CoreResource resource )
     {
         return addResource( resource, GROUPS_URI );
     }
 
     
-    public CoreResource getUser( String id ) throws Exception
+    public EscimoResult getUser( String id )
     {
         return getResource( id, USERS_URI );
     }
 
     
-    public CoreResource getGroup( String id ) throws Exception
+    public EscimoResult getGroup( String id )
     {
         return getResource( id, GROUPS_URI );
     }
 
-    public boolean deleteUser( String id ) throws Exception
+    public EscimoResult deleteUser( String id )
     {
         return deleteResource( id, USERS_URI );
     }
 
-    public boolean deleteGroup( String id ) throws Exception
+    public EscimoResult deleteGroup( String id )
     {
         return deleteResource( id, GROUPS_URI );
     }
 
-    public CoreResource putUser( String userId, CoreResource resource ) throws Exception
+    public EscimoResult putUser( String userId, CoreResource resource )
     {
         return putResource( userId, resource, USERS_URI );
     }
 
     
-    public CoreResource putGroup( String groupId, CoreResource resource ) throws Exception
+    public EscimoResult putGroup( String groupId, CoreResource resource )
     {
         return putResource( groupId, resource, GROUPS_URI );
     }
 
-    public CoreResource patchUser( String userId, CoreResource resource ) throws Exception
+    public EscimoResult patchUser( String userId, CoreResource resource )
     {
         return patchResource( userId, resource, USERS_URI );
     }
 
     
-    public CoreResource patchGroup( String groupId, CoreResource resource ) throws Exception
+    public EscimoResult patchGroup( String groupId, CoreResource resource )
     {
         return patchResource( groupId, resource, GROUPS_URI );
     }
 
     
-    private boolean deleteResource( String id, String uri ) throws Exception
+    private EscimoResult deleteResource( String id, String uri )
     {
 
         if ( id == null )
@@ -144,7 +145,7 @@ public class EscimoClient
             throw new IllegalArgumentException( "resource ID cannot be null" );
         }
 
-        HttpDelete get = new HttpDelete( providerUrl + uri + "/" + id );
+        HttpDelete delete = new HttpDelete( providerUrl + uri + "/" + id );
         
         LOG.debug( "Trying to delete resource with ID {} at URI {}", id, uri );
 
@@ -152,25 +153,32 @@ public class EscimoClient
 
         try
         {
-            HttpResponse resp = client.execute( get );
+            HttpResponse resp = client.execute( delete );
             StatusLine sl = resp.getStatusLine();
             
+            EscimoResult result = new EscimoResult( sl.getStatusCode(), resp.getAllHeaders() );
+            
             if ( sl.getStatusCode() == 200 )
             {
-                return true;
+                return result;
             }
+            else
+            {
+                String retVal = EntityUtils.toString( resp.getEntity() );
+                result.setErrorResponse( deserializeError( retVal ) );
+            }
+            
+            return result;
         }
         catch ( Exception e )
         {
-            LOG.warn( "", e );
-            throw e;
+            LOG.warn( "Failed while deleting the resource at {}", delete.getURI() );
+            throw new RuntimeException( e );
         }
-        
-        return false;
     }
     
     
-    private CoreResource getResource( String id, String uri ) throws Exception
+    private EscimoResult getResource( String id, String uri )
     {
         if ( id == null )
         {
@@ -187,25 +195,31 @@ public class EscimoClient
         {
             HttpResponse resp = client.execute( get );
             StatusLine sl = resp.getStatusLine();
+
+            EscimoResult result = new EscimoResult( sl.getStatusCode(), resp.getAllHeaders() );
             
+            String retVal = EntityUtils.toString( resp.getEntity() );
+
             if ( sl.getStatusCode() == 200 )
             {
-                String retVal = EntityUtils.toString( resp.getEntity() );
-                
-                return deserialize( retVal );
+                result.setResource( deserialize( retVal ) );
             }
+            else
+            {
+                result.setErrorResponse( deserializeError( retVal ) );
+            }
+            
+            return result;
         }
         catch ( Exception e )
         {
-            LOG.warn( "", e );
-            throw e;
+            LOG.warn( "Failed while retrieving resource from {}", get.getURI() );
+            throw new RuntimeException( e );
         }
-        
-        return null;
     }
 
     
-    private CoreResource addResource( CoreResource resource, String uri ) throws Exception
+    private EscimoResult addResource( CoreResource resource, String uri )
     {
         if ( resource == null )
         {
@@ -227,24 +241,30 @@ public class EscimoClient
             HttpResponse resp = client.execute( post );
             StatusLine sl = resp.getStatusLine();
             
+            EscimoResult result = new EscimoResult( sl.getStatusCode(), resp.getAllHeaders() );
+            
+            String retVal = EntityUtils.toString( resp.getEntity() );
+            
             if ( sl.getStatusCode() == 201 )
             {
-                String retVal = EntityUtils.toString( resp.getEntity() );
-                
-                return deserialize( retVal );
+                result.setResource( deserialize( retVal ) );
             }
+            else
+            {
+                result.setErrorResponse( deserializeError( retVal ) );
+            }
+            
+            return result;
         }
-        catch ( Exception e )
+        catch( Exception e )
         {
-            LOG.warn( "", e );
-            throw e;
+            LOG.warn( "Failed while trying to add a resource at {}", post.getURI() );
+            throw new RuntimeException( e );
         }
-        
-        return null;
     }
 
 
-    private CoreResource putResource( String resourceId, CoreResource resource, String uri ) throws Exception
+    private EscimoResult putResource( String resourceId, CoreResource resource, String uri )
     {
         if ( resource == null )
         {
@@ -267,25 +287,31 @@ public class EscimoClient
         {
             HttpResponse resp = client.execute( put );
             StatusLine sl = resp.getStatusLine();
+
+            EscimoResult result = new EscimoResult( sl.getStatusCode(), resp.getAllHeaders() );
+            
+            String retVal = EntityUtils.toString( resp.getEntity() );
             
             if ( sl.getStatusCode() == 200 )
             {
-                String retVal = EntityUtils.toString( resp.getEntity() );
-                
-                return deserialize( retVal );
+                result.setResource( deserialize( retVal ) );
             }
+            else
+            {
+                result.setErrorResponse( deserializeError( retVal ) );
+            }
+            
+            return result;
         }
         catch ( Exception e )
         {
-            LOG.warn( "", e );
-            throw e;
+            LOG.warn( "Failed while trying to replace a resource at {}", put.getURI() );
+            throw new RuntimeException( e );
         }
-        
-        return null;
     }
 
     
-    private CoreResource patchResource( String resourceId, CoreResource resource, String uri ) throws Exception
+    private EscimoResult patchResource( String resourceId, CoreResource resource, String uri )
     {
         if ( resource == null )
         {
@@ -309,28 +335,40 @@ public class EscimoClient
             HttpResponse resp = client.execute( put );
             StatusLine sl = resp.getStatusLine();
             
+            EscimoResult result = new EscimoResult( sl.getStatusCode(), resp.getAllHeaders() );
+            
+            
             if ( sl.getStatusCode() == 200 )
             {
                 String retVal = EntityUtils.toString( resp.getEntity() );
-                
-                return deserialize( retVal );
+                result.setResource( deserialize( retVal ) );
             }
-            else if ( sl.getStatusCode() == 209 )
+            else if ( sl.getStatusCode() == 204 )
             {
-                return null;
+                // do nothing
+            }
+            else // everything else is an error
+            {
+                String retVal = EntityUtils.toString( resp.getEntity() );
+                result.setErrorResponse( deserializeError( retVal ) );
             }
+            
+            return result;
         }
         catch ( Exception e )
         {
-            LOG.warn( "", e );
-            throw e;
+            LOG.warn( "Failed while trying to patch a resource at {}", put.getURI() );
+            throw new RuntimeException( e );
         }
-        
-        return null;
     }
 
     private CoreResource deserialize( String json )
     {
+        if( json == null )
+        {
+            return null;
+        }
+        
         JsonParser parser = new JsonParser();
         JsonObject obj = ( JsonObject ) parser.parse( json );
 
@@ -366,7 +404,16 @@ public class EscimoClient
         return top;
     }
 
-
+    private ErrorResponse deserializeError( String json )
+    {
+        if( json == null )
+        {
+            return null;
+        }
+        
+        return serializer.fromJson( json, ErrorResponse.class );
+    }
+    
     private JsonObject serialize( CoreResource resource )
     {
         JsonObject json = ( JsonObject ) serializer.toJsonTree( resource );

Added: directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoResult.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoResult.java?rev=1536087&view=auto
==============================================================================
--- directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoResult.java (added)
+++ directory/escimo/trunk/client/src/main/java/org/apache/directory/scim/EscimoResult.java Sun Oct 27 10:50:23 2013
@@ -0,0 +1,137 @@
+/*
+ *   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.directory.scim;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.scim.schema.CoreResource;
+import org.apache.directory.scim.schema.ErrorResponse;
+import org.apache.http.Header;
+
+
+/**
+ * TODO EscimoResult.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class EscimoResult
+{
+    private int httpStatusCode;
+
+    private ErrorResponse errorResponse;
+
+    private CoreResource resource;
+
+    private Header[] headers;
+
+
+    public EscimoResult( int httpStatusCode, Header[] headers )
+    {
+        this.httpStatusCode = httpStatusCode;
+        this.headers = headers;
+    }
+
+    public boolean isSuccess()
+    {
+        return ( errorResponse == null );
+    }
+
+    public Header getHeader( String name )
+    {
+        for ( Header h : headers )
+        {
+            if ( h.getName().equals( name ) )
+            {
+                return h;
+            }
+        }
+
+        return null;
+    }
+
+
+    public List<Header> getHeaders( String name )
+    {
+        List<Header> lst = new ArrayList<Header>();
+
+        for ( Header h : headers )
+        {
+            if ( h.getName().equals( name ) )
+            {
+                lst.add( h );
+            }
+        }
+
+        return lst;
+    }
+
+
+    /**
+     * @return the httpStatusCode
+     */
+    public int getHttpStatusCode()
+    {
+        return httpStatusCode;
+    }
+
+
+    /**
+     * @return the errorResponse
+     */
+    public ErrorResponse getErrorResponse()
+    {
+        return errorResponse;
+    }
+
+
+    /**
+     * @param errorResponse the errorResponse to set
+     */
+    public void setErrorResponse( ErrorResponse errorResponse )
+    {
+        this.errorResponse = errorResponse;
+    }
+
+
+    /**
+     * @return the resource
+     */
+    public CoreResource getResource()
+    {
+        return resource;
+    }
+
+
+    public <T> T getResourceAs( Class<T> typeOfresource )
+    {
+        return ( T ) resource;
+    }
+
+    /**
+     * @param resource the resource to set
+     */
+    public void setResource( CoreResource resource )
+    {
+        this.resource = resource;
+    }
+
+}

Modified: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeHandler.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeHandler.java?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeHandler.java (original)
+++ directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeHandler.java Sun Oct 27 10:50:23 2013
@@ -32,7 +32,7 @@ import com.google.gson.JsonElement;
  */
 public abstract class AttributeHandler
 {
-    public abstract void read( BaseType bt, Object srcResource, RequestContext ctx );
+    public abstract void read( BaseType bt, Object srcResource, RequestContext ctx ) throws Exception;
     
     public abstract void write( BaseType atType, JsonElement jsonData, Object targetEntry, RequestContext ctx ) throws Exception;
     

Modified: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeNotFoundException.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeNotFoundException.java?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeNotFoundException.java (original)
+++ directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/AttributeNotFoundException.java Sun Oct 27 10:50:23 2013
@@ -39,8 +39,7 @@ public class AttributeNotFoundException 
 
     public AttributeNotFoundException( String message, Throwable t )
     {
-        super( t );
-        this.message = message;
+        super( message, t );
     }
 
 }

Added: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ResourceConflictException.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ResourceConflictException.java?rev=1536087&view=auto
==============================================================================
--- directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ResourceConflictException.java (added)
+++ directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ResourceConflictException.java Sun Oct 27 10:50:23 2013
@@ -0,0 +1,46 @@
+/*
+ *   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.directory.scim;
+
+
+/**
+ * TODO ResourceNotFoundException.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class ResourceConflictException extends Exception
+{
+    public ResourceConflictException( String message )
+    {
+        super( message );
+    }
+
+
+    public ResourceConflictException( Throwable t )
+    {
+        super( t );
+    }
+
+
+    public ResourceConflictException( String message, Throwable t )
+    {
+        super( message, t );
+    }
+}

Modified: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ResourceNotFoundException.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ResourceNotFoundException.java?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ResourceNotFoundException.java (original)
+++ directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ResourceNotFoundException.java Sun Oct 27 10:50:23 2013
@@ -27,12 +27,9 @@ package org.apache.directory.scim;
  */
 public class ResourceNotFoundException extends Exception
 {
-    String message;
-
-
     public ResourceNotFoundException( String message )
     {
-        this.message = message;
+        super( message );
     }
 
 
@@ -44,20 +41,7 @@ public class ResourceNotFoundException e
 
     public ResourceNotFoundException( String message, Throwable t )
     {
-        super( t );
-        this.message = message;
-    }
-
-
-    @Override
-    public String getMessage()
-    {
-        if ( message == null )
-        {
-            return super.getMessage();
-        }
-
-        return message;
+        super( message, t );
     }
 
 }

Modified: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ScimUtil.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ScimUtil.java?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ScimUtil.java (original)
+++ directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/ScimUtil.java Sun Oct 27 10:50:23 2013
@@ -19,9 +19,20 @@
 package org.apache.directory.scim;
 
 
+import static org.apache.directory.scim.schema.ErrorCode.BAD_REQUEST;
+import static org.apache.directory.scim.schema.ErrorCode.CONFLICT;
+import static org.apache.directory.scim.schema.ErrorCode.INTERNAL_SERVER_ERROR;
+import static org.apache.directory.scim.schema.ErrorCode.NOT_FOUND;
+
 import java.io.PrintWriter;
 import java.io.StringWriter;
 
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+
+import org.apache.directory.scim.json.ResourceSerializer;
+import org.apache.directory.scim.schema.ErrorCode;
+import org.apache.directory.scim.schema.ErrorResponse;
 
 /**
  * 
@@ -55,4 +66,36 @@ public class ScimUtil
                  CORE_GROUP_URI.equals( uri ) );
     }
 
+    
+    public static ResponseBuilder buildError( Exception e )
+    {
+        // set the default type to server error
+        ErrorCode ec = INTERNAL_SERVER_ERROR;
+        String desc = e.getMessage();
+        
+        if( ( e instanceof AttributeNotFoundException ) || ( e instanceof ResourceNotFoundException ) )
+        {
+            ec = NOT_FOUND;
+        }
+        else if ( e instanceof IllegalArgumentException )
+        {
+            ec = BAD_REQUEST;
+        }
+        else if ( e instanceof ResourceConflictException )
+        {
+            ec = CONFLICT;
+        }
+        
+        ErrorResponse.Error error = new ErrorResponse.Error( ec.getVal(), desc );
+        
+        error.setStackTrace( exceptionToStr( e ) );
+        
+        ErrorResponse erResp = new ErrorResponse( error );
+        
+        String json = ResourceSerializer.serialize( erResp );
+        
+        ResponseBuilder rb = Response.status( ec.getVal() ).entity( json );
+        
+        return rb;
+    }
 }

Modified: directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/json/ResourceSerializer.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/json/ResourceSerializer.java?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/json/ResourceSerializer.java (original)
+++ directory/escimo/trunk/common/src/main/java/org/apache/directory/scim/json/ResourceSerializer.java Sun Oct 27 10:50:23 2013
@@ -30,7 +30,9 @@ import org.apache.directory.scim.ScimUti
 import org.apache.directory.scim.ServerResource;
 import org.apache.directory.scim.SimpleAttribute;
 import org.apache.directory.scim.SimpleAttributeGroup;
+import org.apache.directory.scim.schema.ErrorResponse;
 
+import com.google.gson.Gson;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonPrimitive;
@@ -44,6 +46,13 @@ import com.google.gson.JsonPrimitive;
 public class ResourceSerializer
 {
 
+    private static final JsonArray ERROR_RESPONSE_SCHEMAS = new JsonArray();
+    
+    static
+    {
+        ERROR_RESPONSE_SCHEMAS.add( new JsonPrimitive( ErrorResponse.SCHEMA_ID ) );
+    }
+
     public static String serialize( ServerResource resource )
     {
         JsonObject root = new JsonObject();
@@ -138,4 +147,14 @@ public class ResourceSerializer
             parent.addProperty( at.getName(), ( Boolean ) obj );
         }
     }
+    
+    public static String serialize( ErrorResponse err )
+    {
+        Gson gson = new Gson();
+        JsonObject jo = ( JsonObject ) gson.toJsonTree( err );
+        
+        jo.add( "schemas", ERROR_RESPONSE_SCHEMAS );
+        
+        return jo.toString();
+    }
 }

Modified: directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapResourceProvider.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapResourceProvider.java?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapResourceProvider.java (original)
+++ directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/LdapResourceProvider.java Sun Oct 27 10:50:23 2013
@@ -41,6 +41,7 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.ldap.model.entry.DefaultEntry;
 import org.apache.directory.api.ldap.model.entry.Entry;
 import org.apache.directory.api.ldap.model.entry.Value;
+import org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException;
 import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.message.LdapResult;
 import org.apache.directory.api.ldap.model.message.ModifyRequest;
@@ -69,8 +70,10 @@ import org.apache.directory.scim.Complex
 import org.apache.directory.scim.GroupResource;
 import org.apache.directory.scim.MissingParameterException;
 import org.apache.directory.scim.MultiValAttribute;
+import org.apache.directory.scim.OperationException;
 import org.apache.directory.scim.ProviderService;
 import org.apache.directory.scim.RequestContext;
+import org.apache.directory.scim.ResourceConflictException;
 import org.apache.directory.scim.ResourceNotFoundException;
 import org.apache.directory.scim.ServerResource;
 import org.apache.directory.scim.SimpleAttribute;
@@ -267,12 +270,12 @@ public class LdapResourceProvider implem
     {
         if ( Strings.isEmpty( id ) )
         {
-            throw new MissingParameterException( "id cannot be null or empty" );
+            throw new MissingParameterException( "parameter 'id' cannot be null or empty" );
         }
 
         if ( Strings.isEmpty( atName ) )
         {
-            throw new MissingParameterException( "atName cannot be null or empty" );
+            throw new MissingParameterException( "parameter 'atName' cannot be null or empty" );
         }
 
         Entry entry = fetchEntryById( id, userSchema );
@@ -358,6 +361,8 @@ public class LdapResourceProvider implem
     
     public UserResource addUser( String json, RequestContext ctx ) throws Exception
     {
+        String userName = null;
+        
         try
         {
             JsonParser parser = new JsonParser();
@@ -377,7 +382,7 @@ public class LdapResourceProvider implem
             
             if( dn == null )
             {
-                String userName = obj.get( "userName" ).getAsString();
+                userName = obj.get( "userName" ).getAsString();
                 
                 dn = userIdName + "=" + userName + "," + userSchema.getBaseDn();
             }
@@ -398,6 +403,11 @@ public class LdapResourceProvider implem
             return addedUser;
 
         }
+        catch( LdapEntryAlreadyExistsException e )
+        {
+            String message = "Resource already exists, conflicting attribute userName : " + userName;
+            throw new ResourceConflictException( message );
+        }
         catch( Exception e )
         {
             LOG.warn( "Failed to create User resource", e );
@@ -408,6 +418,8 @@ public class LdapResourceProvider implem
     
     public GroupResource addGroup( String jsonData, RequestContext ctx ) throws Exception
     {
+        String groupName = null;
+        
         try
         {
             JsonParser parser = new JsonParser();
@@ -427,7 +439,7 @@ public class LdapResourceProvider implem
             
             if( dn == null )
             {
-                String groupName = obj.get( "displayName" ).getAsString();
+                groupName = obj.get( "displayName" ).getAsString();
                 
                 dn = groupNameAt + "=" + groupName + "," + groupSchema.getBaseDn();
             }
@@ -449,6 +461,11 @@ public class LdapResourceProvider implem
             return addedGroup;
 
         }
+        catch( LdapEntryAlreadyExistsException e )
+        {
+            String message = "Resource already exists, conflicting attribute displayName : " + groupName;
+            throw new ResourceConflictException( message );
+        }
         catch( Exception e )
         {
             LOG.warn( "Failed to create Group resource", e );
@@ -772,8 +789,7 @@ public class LdapResourceProvider implem
     }
 
 
-    private void _loadAttributes( RequestContext ctx, Entry entry, Collection<BaseType> types, SimpleType idType )
-        throws Exception
+    private void _loadAttributes( RequestContext ctx, Entry entry, Collection<BaseType> types, SimpleType idType ) throws Exception
     {
         ServerResource user = ctx.getCoreResource();
 
@@ -860,7 +876,7 @@ public class LdapResourceProvider implem
     }
 
 
-    private List<SimpleAttributeGroup> getValuesFor( SimpleTypeGroup stg, Entry entry ) throws LdapException
+    private List<SimpleAttributeGroup> getValuesFor( SimpleTypeGroup stg, Entry entry )
     {
         if ( stg == null )
         {
@@ -918,7 +934,7 @@ public class LdapResourceProvider implem
     }
 
 
-    public SimpleAttribute getValueForSimpleType( SimpleType st, Entry entry, RequestContext ctx ) throws LdapException
+    public SimpleAttribute getValueForSimpleType( SimpleType st, Entry entry, RequestContext ctx ) throws Exception
     {
         String atHandler = st.getAtHandlerName();
 
@@ -935,7 +951,7 @@ public class LdapResourceProvider implem
     }
 
 
-    public SimpleAttribute getValueForSimpleType( SimpleType st, Entry entry ) throws LdapException
+    public SimpleAttribute getValueForSimpleType( SimpleType st, Entry entry )
     {
         String name = st.getName();
         Attribute at = entry.get( st.getMappedTo() );
@@ -950,13 +966,13 @@ public class LdapResourceProvider implem
     }
 
 
-    private Object getScimValFrom( Attribute at ) throws LdapException
+    private Object getScimValFrom( Attribute at )
     {
         return getScimValFrom( at.get() );
     }
 
 
-    private Object getScimValFrom( Value<?> ldapValue ) throws LdapException
+    private Object getScimValFrom( Value<?> ldapValue )
     {
         if ( !ldapValue.isHumanReadable() )
         {
@@ -985,12 +1001,7 @@ public class LdapResourceProvider implem
     }
 
 
-    //    public List<SimpleAttribute> getValuesInto( SimpleTypeGroup stg, RequestContext ctx ) throws LdapException
-    //    {
-    //        
-    //    }
-
-    public List<SimpleAttribute> getValuesInto( SimpleTypeGroup stg, Entry entry ) throws LdapException
+    public List<SimpleAttribute> getValuesInto( SimpleTypeGroup stg, Entry entry )
     {
         List<SimpleAttribute> lstAts = new ArrayList<SimpleAttribute>();
 

Modified: directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/ActiveAttributeHandler.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/ActiveAttributeHandler.java?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/ActiveAttributeHandler.java (original)
+++ directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/ActiveAttributeHandler.java Sun Oct 27 10:50:23 2013
@@ -40,7 +40,7 @@ public class ActiveAttributeHandler exte
     private static final Logger LOG = LoggerFactory.getLogger( ActiveAttributeHandler.class );
     
     @Override
-    public void read( BaseType bt, Object srcResource, RequestContext ctx )
+    public void read( BaseType bt, Object srcResource, RequestContext ctx ) throws Exception
     {
         if( !bt.getName().equals( "active" ) )
         {
@@ -66,6 +66,7 @@ public class ActiveAttributeHandler exte
             catch( LdapException e )
             {
                 LOG.warn( "Failed to get the value for the attribute {}", bt.getName(), e );
+                throw e;
             }
         }
         

Modified: directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/GroupsAttributeHandler.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/GroupsAttributeHandler.java?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/GroupsAttributeHandler.java (original)
+++ directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/GroupsAttributeHandler.java Sun Oct 27 10:50:23 2013
@@ -62,7 +62,7 @@ public class GroupsAttributeHandler exte
 
 
     @Override
-    public void read( BaseType bt, Object srcResource, RequestContext ctx )
+    public void read( BaseType bt, Object srcResource, RequestContext ctx ) throws Exception
     {
         if ( !bt.getName().equals( "groups" ) )
         {
@@ -119,6 +119,7 @@ public class GroupsAttributeHandler exte
                 catch ( LdapException ex )
                 {
                     LOG.warn( "Failed to get attributes from entry {}", memberEntry.getDn() );
+                    throw ex;
                 }
             }
 
@@ -147,7 +148,7 @@ public class GroupsAttributeHandler exte
 
 
     private List<Entry> getMemberEntriesUsingFilter( String filter, String baseDn, Entry userEntry,
-        LdapResourceProvider provider )
+        LdapResourceProvider provider ) throws Exception
     {
         if ( Strings.isEmpty( baseDn ) )
         {
@@ -182,6 +183,7 @@ public class GroupsAttributeHandler exte
         {
             LOG.warn( "Failed to get the groups using the filter {} and base DN {}", filter, baseDn );
             LOG.warn( "", e );
+            throw e;
         }
 
         return lst;
@@ -263,6 +265,7 @@ public class GroupsAttributeHandler exte
                             catch ( LdapException e )
                             {
                                 LOG.warn( "Failed to set the value for the attribute {} in the filter", at );
+                                throw new RuntimeException( e );
                             }
                         }
                     }

Modified: directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MembersAttributeHandler.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MembersAttributeHandler.java?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MembersAttributeHandler.java (original)
+++ directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MembersAttributeHandler.java Sun Oct 27 10:50:23 2013
@@ -70,7 +70,7 @@ public class MembersAttributeHandler ext
 
 
     @Override
-    public void read( BaseType bt, Object srcResource, RequestContext ctx )
+    public void read( BaseType bt, Object srcResource, RequestContext ctx ) throws Exception
     {
         checkHandler( bt, "members", this );
         
@@ -266,7 +266,7 @@ public class MembersAttributeHandler ext
         return memberType;
     }
     
-    private SimpleAttributeGroup getMemberDetails( String dn, RequestContext ctx )
+    private SimpleAttributeGroup getMemberDetails( String dn, RequestContext ctx ) throws Exception
     {
         LdapResourceProvider provider = ( LdapResourceProvider ) ctx.getProviderService();
 
@@ -302,6 +302,7 @@ public class MembersAttributeHandler ext
         catch ( LdapException ex )
         {
             LOG.warn( "Failed to get attributes from entry {}", memberEntry.getDn() );
+            throw ex;
         }
 
         return sg;
@@ -309,7 +310,7 @@ public class MembersAttributeHandler ext
 
 
     private List<Entry> getMemberEntriesUsingFilter( String filter, String baseDn, Entry userEntry,
-        LdapResourceProvider provider )
+        LdapResourceProvider provider ) throws Exception
     {
         if ( Strings.isEmpty( baseDn ) )
         {
@@ -344,6 +345,7 @@ public class MembersAttributeHandler ext
         {
             LOG.warn( "Failed to get the groups using the filter {} and base DN {}", filter, baseDn );
             LOG.warn( "", e );
+            throw e;
         }
 
         return lst;
@@ -425,6 +427,7 @@ public class MembersAttributeHandler ext
                             catch ( LdapException e )
                             {
                                 LOG.warn( "Failed to set the value for the attribute {} in the filter", at );
+                                throw new RuntimeException( e );
                             }
                         }
                     }

Modified: directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MetaAttributeHandler.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MetaAttributeHandler.java?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MetaAttributeHandler.java (original)
+++ directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/MetaAttributeHandler.java Sun Oct 27 10:50:23 2013
@@ -47,7 +47,7 @@ public class MetaAttributeHandler extend
     private static final Logger LOG = LoggerFactory.getLogger( ActiveAttributeHandler.class );
     
     @Override
-    public void read( BaseType bt, Object srcResource, RequestContext ctx )
+    public void read( BaseType bt, Object srcResource, RequestContext ctx ) throws Exception
     {
         Entry entry = ( Entry ) srcResource;
 
@@ -108,6 +108,7 @@ public class MetaAttributeHandler extend
         catch( LdapException e )
         {
             LOG.warn( "Failed while creating meta attribute", e );
+            throw e;
         }
         
     }

Modified: directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/PhotosAttributeHandler.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/PhotosAttributeHandler.java?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/PhotosAttributeHandler.java (original)
+++ directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/PhotosAttributeHandler.java Sun Oct 27 10:50:23 2013
@@ -59,7 +59,7 @@ public class PhotosAttributeHandler exte
 
 
     @Override
-    public void read( BaseType bt, Object srcResource, RequestContext ctx )
+    public void read( BaseType bt, Object srcResource, RequestContext ctx ) throws Exception
     {
         checkHandler( bt, "photos", this );
 
@@ -95,7 +95,7 @@ public class PhotosAttributeHandler exte
     }
 
 
-    private SimpleAttribute getPhotoUrlValue( SimpleTypeGroup stg, Entry entry, String photoUrlBase, ServerResource user )
+    private SimpleAttribute getPhotoUrlValue( SimpleTypeGroup stg, Entry entry, String photoUrlBase, ServerResource user ) throws Exception
     {
         SimpleType valType = stg.getValueType();
         if ( valType != null )
@@ -114,21 +114,14 @@ public class PhotosAttributeHandler exte
     }
 
 
-    private String formatPhotoUrl( String url, String atName, String userId, byte[] photoBytes )
+    private String formatPhotoUrl( String url, String atName, String userId, byte[] photoBytes ) throws Exception
     {
         String enc = "UTF-8";
-        try
-        {
-            atName = URLEncoder.encode( atName, enc );
-            userId = URLEncoder.encode( userId, enc );
 
-            return String.format( url, atName, userId );
-        }
-        catch ( Exception e )
-        {
-            // if happens blow up 
-            throw new RuntimeException( e );
-        }
+        atName = URLEncoder.encode( atName, enc );
+        userId = URLEncoder.encode( userId, enc );
+        
+        return String.format( url, atName, userId );
     }
 
 

Added: directory/escimo/trunk/schema/src/main/java/org/apache/directory/scim/schema/ErrorCode.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/schema/src/main/java/org/apache/directory/scim/schema/ErrorCode.java?rev=1536087&view=auto
==============================================================================
--- directory/escimo/trunk/schema/src/main/java/org/apache/directory/scim/schema/ErrorCode.java (added)
+++ directory/escimo/trunk/schema/src/main/java/org/apache/directory/scim/schema/ErrorCode.java Sun Oct 27 10:50:23 2013
@@ -0,0 +1,73 @@
+/*
+ *   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.directory.scim.schema;
+
+/**
+ * TODO ErrorCode.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public enum ErrorCode
+{
+
+    BAD_REQUEST(400, "Request is unparseable, syntactically incorrect, or violates schema"),
+    
+    UNAUTHORIZED(401, "Authorization failure"),
+    
+    FORBIDDEN(403, "Server does not support requested operation"),
+    
+    NOT_FOUND(404, "Specified resource does not exist"),
+    
+    CONFLICT(409, "The specified version number does not match the resource's latest version number or a Service Provider refused to create a new, duplicate resource"),
+    
+    PRECONDITION_FAILED(412, "Failed to update as Resource changed on the server since last retrieved"),
+    
+    REQUEST_ENTITY_TOO_LARGE(413, "Requested entity too large"),
+    
+    INTERNAL_SERVER_ERROR(500, "Internal server error"),
+    
+    NOT_IMPLEMENTED(501, "Service Provider does not support the requested operation");
+    
+    private int val;
+    
+    private String desc;
+    
+    private ErrorCode( int val, String desc )
+    {
+        this.val = val;
+        this.desc = desc;
+    }
+
+    /**
+     * @return the val
+     */
+    public int getVal()
+    {
+        return val;
+    }
+
+    /**
+     * @return the desc
+     */
+    public String getDesc()
+    {
+        return desc;
+    }
+}

Added: directory/escimo/trunk/schema/src/main/java/org/apache/directory/scim/schema/ErrorResponse.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/schema/src/main/java/org/apache/directory/scim/schema/ErrorResponse.java?rev=1536087&view=auto
==============================================================================
--- directory/escimo/trunk/schema/src/main/java/org/apache/directory/scim/schema/ErrorResponse.java (added)
+++ directory/escimo/trunk/schema/src/main/java/org/apache/directory/scim/schema/ErrorResponse.java Sun Oct 27 10:50:23 2013
@@ -0,0 +1,137 @@
+/*
+ *   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.directory.scim.schema;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * TODO ErrorResponse.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class ErrorResponse
+{
+    public static final String SCHEMA_ID = "urn:scim:schemas:core:2.0:Error";
+
+    // named the variable with uppercase 'E'
+    // to allow direct serialization using Gson
+    private List<Error> Errors;
+
+
+    public ErrorResponse( Error error )
+    {
+        addError( error );
+    }
+
+
+    public int getFirstErrorCode()
+    {
+        return Errors.get( 0 ).getCode();
+    }
+    
+    public String getFirstErrorDesc()
+    {
+        return Errors.get( 0 ).getDescription();
+    }
+
+    public void addError( Error error )
+    {
+        if ( Errors == null )
+        {
+            Errors = new ArrayList<Error>();
+        }
+
+        Errors.add( error );
+    }
+
+
+    /**
+     * @return the errors
+     */
+    public List<Error> getErrors()
+    {
+        return Errors;
+    }
+
+
+    /**
+     * @param errors the errors to set
+     */
+    public void setErrors( List<Error> errors )
+    {
+        this.Errors = errors;
+    }
+
+    public static class Error
+    {
+        private String description;
+        
+        private int code;
+
+        // this is an eSCIMo specific field used for 
+        // debugging purpose
+        private String stackTrace;
+
+        public Error( int code, String description )
+        {
+            this.code = code;
+            this.description = description;
+        }
+
+
+        /**
+         * @return the stackTrace
+         */
+        public String getStackTrace()
+        {
+            return stackTrace;
+        }
+
+
+        /**
+         * @param stackTrace the stackTrace to set
+         */
+        public void setStackTrace( String stackTrace )
+        {
+            this.stackTrace = stackTrace;
+        }
+
+
+        /**
+         * @return the description
+         */
+        public String getDescription()
+        {
+            return description;
+        }
+
+
+        /**
+         * @return the code
+         */
+        public int getCode()
+        {
+            return code;
+        }
+    }
+}

Modified: directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/UserService.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/UserService.java?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/UserService.java (original)
+++ directory/escimo/trunk/server/src/main/java/org/apache/directory/scim/rest/UserService.java Sun Oct 27 10:50:23 2013
@@ -18,8 +18,6 @@
  */
 package org.apache.directory.scim.rest;
 
-import static org.apache.directory.scim.ScimUtil.exceptionToStr;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -43,11 +41,10 @@ import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.StreamingOutput;
 import javax.ws.rs.core.UriInfo;
 
-import org.apache.directory.scim.AttributeNotFoundException;
 import org.apache.directory.scim.MissingParameterException;
 import org.apache.directory.scim.ProviderService;
 import org.apache.directory.scim.RequestContext;
-import org.apache.directory.scim.ResourceNotFoundException;
+import org.apache.directory.scim.ScimUtil;
 import org.apache.directory.scim.ServerResource;
 import org.apache.directory.scim.UserResource;
 import org.apache.directory.scim.json.ResourceSerializer;
@@ -81,9 +78,9 @@ public class UserService
             String json = ResourceSerializer.serialize( user );
             rb = Response.ok( json, MediaType.APPLICATION_JSON );
         }
-        catch( ResourceNotFoundException e )
+        catch( Exception e )
         {
-            rb = Response.status( Status.INTERNAL_SERVER_ERROR ).entity( exceptionToStr( e ) );
+            rb = ScimUtil.buildError( e );
         }
         
         return rb.build();
@@ -102,7 +99,7 @@ public class UserService
         }
         catch( Exception e )
         {
-            rb = Response.status( Status.INTERNAL_SERVER_ERROR ).entity( exceptionToStr( e ) );
+            rb = ScimUtil.buildError( e );
         }
         
         return rb.build();
@@ -139,7 +136,7 @@ public class UserService
         }
         catch( Exception e )
         {
-            rb = Response.status( Status.INTERNAL_SERVER_ERROR ).entity( exceptionToStr( e ) );
+            rb = ScimUtil.buildError( e );
         }
         
         return rb.build();
@@ -175,7 +172,7 @@ public class UserService
         }
         catch( Exception e )
         {
-            rb = Response.status( Status.INTERNAL_SERVER_ERROR ).entity( exceptionToStr( e ) );
+            rb = ScimUtil.buildError( e );
         }
         
         return rb.build();
@@ -213,13 +210,9 @@ public class UserService
                 rb = Response.ok().entity( json );
             }
         }
-        catch( AttributeNotFoundException e )
-        {
-            rb = Response.status( Status.NOT_FOUND ).entity( exceptionToStr( e ) );
-        }
         catch( Exception e )
         {
-            rb = Response.status( Status.INTERNAL_SERVER_ERROR ).entity( exceptionToStr( e ) );
+            rb = ScimUtil.buildError( e );
         }
         
         return rb.build();
@@ -231,14 +224,14 @@ public class UserService
     @Path("photo")
     public Response getPhoto( @QueryParam("atName") String atName, @QueryParam("id") String id )
     {
-        final ResponseBuilder rb = Response.ok();
+        ResponseBuilder rb = Response.ok();
         
         try
         {
             final InputStream in = provider.getUserPhoto( id, atName );
             if( in == null )
             {
-                rb.status( Status.NOT_FOUND );
+                rb.status( Status.NOT_FOUND ).entity( "No photo found for the resource with ID " + id + " and attribute name " + atName );
             }
             else
             {
@@ -262,10 +255,6 @@ public class UserService
                                 output.write( buf, 0, read );
                             }
                         }
-                        catch( IOException e )
-                        {
-                            rb.status( Status.INTERNAL_SERVER_ERROR ).entity( exceptionToStr( e ) );
-                        }
                         finally
                         {
                             in.close();
@@ -278,7 +267,7 @@ public class UserService
         }
         catch( MissingParameterException e )
         {
-            rb.status( Status.BAD_REQUEST ).entity( exceptionToStr( e ) );
+            rb = ScimUtil.buildError( e );
         }
         
         return rb.build();

Modified: directory/escimo/trunk/tests/src/test/java/org/apache/directory/scim/UserResourceTest.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/tests/src/test/java/org/apache/directory/scim/UserResourceTest.java?rev=1536087&r1=1536086&r2=1536087&view=diff
==============================================================================
--- directory/escimo/trunk/tests/src/test/java/org/apache/directory/scim/UserResourceTest.java (original)
+++ directory/escimo/trunk/tests/src/test/java/org/apache/directory/scim/UserResourceTest.java Sun Oct 27 10:50:23 2013
@@ -37,6 +37,7 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.scim.User.Email;
 import org.apache.directory.scim.User.Name;
 import org.apache.directory.scim.schema.CoreResource;
+import org.apache.directory.scim.schema.ErrorCode;
 import org.apache.directory.scim.schema.MetaData;
 import org.apache.directory.server.core.api.CoreSession;
 import org.apache.directory.server.core.api.LdapCoreSessionConnection;
@@ -94,19 +95,30 @@ public class UserResourceTest
         emails.add( mail );
         user.setEmails( emails );
         
-        User addedUser = ( User ) client.addUser( user );
+        EscimoResult result = client.addUser( user );
+        assertTrue( result.isSuccess() );
+        
+        User addedUser = ( User ) result.getResource(); 
         
         assertNotNull( addedUser );
         
         assertEquals( user.getUserName(), addedUser.getUserName() );
         
-        User fetchedUser = ( User ) client.getUser( addedUser.getId() );
+        result = client.getUser( addedUser.getId() );
+        User fetchedUser = result.getResourceAs( User.class );
         
         assertEquals( addedUser.getUserName(), fetchedUser.getUserName() );
         assertEquals( addedUser.getId(), fetchedUser.getId() );
         
-        client.deleteUser( fetchedUser.getId() );
-        fetchedUser = ( User ) client.getUser( addedUser.getId() );
+        result = client.addUser( user );
+        assertFalse( result.isSuccess() );
+        assertEquals( ErrorCode.CONFLICT.getVal(), result.getErrorResponse().getFirstErrorCode() );
+        
+        result = client.deleteUser( fetchedUser.getId() );
+        assertTrue( result.isSuccess() );
+        
+        result = client.getUser( addedUser.getId() );
+        fetchedUser = result.getResourceAs( User.class );
         assertNull( fetchedUser );
     }
     
@@ -130,7 +142,11 @@ public class UserResourceTest
         emails.add( mail );
         user.setEmails( emails );
 
-        User addedUser = ( User ) client.addUser( user );
+        EscimoResult result = client.addUser( user );
+        assertTrue( result.isSuccess() );
+        
+        User addedUser = ( User ) result.getResource(); 
+
         assertNotNull( addedUser );
 
         addedUser.getEmails().clear();
@@ -139,7 +155,8 @@ public class UserResourceTest
         newEmail.setValue( "newemail@example.com" );
         addedUser.getEmails().add( newEmail );
         
-        User replacedUser = ( User ) client.putUser( addedUser.getId(), addedUser );
+        result = client.putUser( addedUser.getId(), addedUser );
+        User replacedUser = result.getResourceAs( User.class );
 
         assertNotNull( replacedUser );
         assertEquals( 1, replacedUser.getEmails().size() );
@@ -167,7 +184,11 @@ public class UserResourceTest
         emails.add( mail );
         user.setEmails( emails );
 
-        User addedUser = ( User ) client.addUser( user );
+        EscimoResult result = client.addUser( user );
+        assertTrue( result.isSuccess() );
+        
+        User addedUser = ( User ) result.getResource(); 
+
         assertNotNull( addedUser );
 
         addedUser.getEmails().get( 0 ).setOperation( "delete" );
@@ -182,11 +203,13 @@ public class UserResourceTest
             addedUser.getEmails().add( newEmail );
         }
         
-        User patchedUser = ( User ) client.patchUser( addedUser.getId(), addedUser );
+        result = client.patchUser( addedUser.getId(), addedUser );
+        User patchedUser = result.getResourceAs( User.class );
 
         assertNull( patchedUser );
         
-        patchedUser = ( User ) client.getUser( addedUser.getId() );
+        result = client.getUser( addedUser.getId() );
+        patchedUser = result.getResourceAs( User.class ); 
         assertNotNull( patchedUser );
         
         for( Email e : patchedUser.getEmails() )
@@ -229,7 +252,11 @@ public class UserResourceTest
             count++;
         }
         
-        Group addedGroup = ( Group ) client.addGroup( group );
+        EscimoResult result = client.addGroup( group );
+        assertTrue( result.isSuccess() );
+        
+        Group addedGroup = result.getResourceAs( Group.class );
+        
         assertNotNull( addedGroup );
         assertEquals( group.getDisplayName(), addedGroup.getDisplayName() );
         assertNotNull( addedGroup.getId() );
@@ -246,7 +273,10 @@ public class UserResourceTest
         patchedMembers.add( deletedMember );
         
         client.patchGroup( addedGroup.getId(), tobePatchedGroup );
-        Group patchedGroup = ( Group ) client.getGroup( addedGroup.getId() );
+        
+        result = client.getGroup( addedGroup.getId() );
+        Group patchedGroup = result.getResourceAs( Group.class );
+
         assertEquals( ( count - 1 ), patchedGroup.getMembers().size() );
         
         for( Group.Member gm : patchedGroup.getMembers() )
@@ -264,7 +294,8 @@ public class UserResourceTest
         meta.setAttributes( attributes );
         deleteMemGroup.setMeta( meta );
         
-        patchedGroup = ( Group ) client.patchGroup( addedGroup.getId(), deleteMemGroup );
+        result = client.patchGroup( addedGroup.getId(), deleteMemGroup );
+        patchedGroup = result.getResourceAs( Group.class ); 
         assertNull( patchedGroup.getMembers() );
     }
 }