cleaning up MIFOSX-1947

This commit is contained in:
Vishwas Babu A J
2015-04-10 23:57:36 -07:00
parent 72be7a82a5
commit f883158001
12 changed files with 228 additions and 424 deletions
+41 -266
View File
@@ -1796,6 +1796,26 @@
<td><a href="#staff_update">Update a Staff Member</a></td> <td><a href="#staff_update">Update a Staff Member</a></td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td><a href="#client_images">Staff Images</a></td>
<td>staff/{staffId}/images</td>
<td><a href="#client_images_create">Upload an Image for a Staff Member (as DATA URI)</a></td>
<td><a href="#client_images_retrieve">Get Staff Image (DATA URI)</a></td>
<td><a href="#client_images_update">Update Staff Image (DATA URI)</a></td>
<td><a href="#client_images_delete">Delete Staff Image</a></td>
</tr>
<tr>
<td></td>
<td></td>
<td><a href="#client_images_create_form">
Upload an Image for a Staff Member (Multi-part form data)</a>
</td>
<td><a href="#client_images_retrieve_binary">Get Staff Image (Binary file)</a></td>
<td><a href="#client_images_update_form">
Update Staff Image (Multi-part form data)</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td><a href="#charges">Charges</a></td> <td><a href="#charges">Charges</a></td>
<td>charges</td> <td>charges</td>
@@ -4709,12 +4729,12 @@ No Request Body:
<a id="client_images" name="client_images" class="old-syle-anchor">&nbsp;</a> <a id="client_images" name="client_images" class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h3>Client Images</h3> <h3>Images</h3>
<p>The current API provides support for the addition of a single <p>The current API provides support for the addition of a single
image for a Client<br/> image for entities like Client (URL pattern <i>/clients</i>) and Staff (URL pattern <i>/staff</i>)<br/>
Allowed formats: JPEG (.jpg or .jpeg), GIF (.gif) and PNG (.png) Allowed formats: JPEG (.jpg or .jpeg), GIF (.gif) and PNG (.png)
</p> </p>
<p> The API supports two different Approaches for manipulating Client Images <p> The API supports two different Approaches for manipulating Images
<ul> <ul>
<li><a href="http://en.wikipedia.org/wiki/Data_URI_scheme" target="_blank"> Data URI's: </a> <li><a href="http://en.wikipedia.org/wiki/Data_URI_scheme" target="_blank"> Data URI's: </a>
For easier manipulation by Javascript clients etc in supported Browsers. For easier manipulation by Javascript clients etc in supported Browsers.
@@ -4731,10 +4751,11 @@ No Request Body:
class="old-syle-anchor">&nbsp;</a> class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h4>Get Client Image (DATA URI)</h4> <h4>Get Entity Image (DATA URI)</h4>
<p>Optional arguments are identical to those of <a href="#client_images_retrieve_binary">Get Client Image (Binary file)</a></p> <p>Optional arguments are identical to those of <a href="#client_images_retrieve_binary">Get Image associated with an Entity (Binary file)</a></p>
<p>Example Requests:</p> <p>Example Requests:</p>
<div class=apiClick>clients/1/images</div> <div class=apiClick>clients/1/images</div>
<div class=apiClick>staff/1/images</div>
<br> <br>
</div> </div>
<div class="method-example"> <div class="method-example">
@@ -4757,7 +4778,7 @@ gAEAOg13B6R/SAgAAAAASUVORK5CYII=
class="old-syle-anchor">&nbsp;</a> class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h4>Get Client Image (Binary file)</h4> <h4>Get Image associated with an Entity (Binary file)</h4>
<h5>Optional Arguments</h5> <h5>Optional Arguments</h5>
<dl class="argument-list"> <dl class="argument-list">
<dt>output</dt> <dt>output</dt>
@@ -4791,7 +4812,7 @@ GET https://DomainName/api/v1/clients/{clientId}/images
Accept: application/octet-stream Accept: application/octet-stream
</code> </code>
<code class="method-request"> <code class="method-request">
POST clients/1/images GET clients/1/images
Accept: application/octet-stream Accept: application/octet-stream
</code> </code>
<code class="method-response"> <code class="method-response">
@@ -4803,7 +4824,7 @@ Accept: application/octet-stream
<a id="client_images_create" name="client_images_create" class="old-syle-anchor">&nbsp;</a> <a id="client_images_create" name="client_images_create" class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h4>Upload an Image for a Client (Data URI)</h4> <h4>Upload an Image for an Entity (Data URI)</h4>
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration"> <code class="method-declaration">
@@ -4831,7 +4852,7 @@ P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC
<a id="client_images_create_form" name="client_images_create_form" class="old-syle-anchor">&nbsp;</a> <a id="client_images_create_form" name="client_images_create_form" class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h4>Upload an Image for a Client (Multi-part Form data)</h4> <h4>Upload an Image for an Entity (Multi-part Form data)</h4>
<table class=matrixHeading> <table class=matrixHeading>
<tr class="matrixHeadingBG"> <tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Mandatory Fields</div></td> <td><div class="mifosXHeading2">Mandatory Fields</div></td>
@@ -4871,7 +4892,7 @@ Request Body: <i>Not shown</i>
<a id="client_images_update" name="client_images_update" class="old-syle-anchor">&nbsp;</a> <a id="client_images_update" name="client_images_update" class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h4>Update a Client Image (Data URI)</h4> <h4>Update a Image associated with an Entity (Data URI)</h4>
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration"> <code class="method-declaration">
@@ -4899,7 +4920,7 @@ P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC
<a id="client_images_update_form" name="client_images_update_form" class="old-syle-anchor">&nbsp;</a> <a id="client_images_update_form" name="client_images_update_form" class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h4>Update a Client Image (Multi-part Form data)</h4> <h4>Update an Entity's Image (Multi-part Form data)</h4>
<table class=matrixHeading> <table class=matrixHeading>
<tr class="matrixHeadingBG"> <tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Mandatory Fields</div></td> <td><div class="mifosXHeading2">Mandatory Fields</div></td>
@@ -4932,7 +4953,7 @@ Request Body: <i>Not shown</i>
<a id="client_images_delete" name="client_images_delete" class="old-syle-anchor">&nbsp;</a> <a id="client_images_delete" name="client_images_delete" class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h4>Delete a Client Image</h4> <h4>Delete an Entity's Image</h4>
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration"> <code class="method-declaration">
@@ -16767,252 +16788,7 @@ Request Body:
</div> </div>
</div> </div>
<a id="staff_images" name="staff_images" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h3>Staff Images</h3>
<p>The current API provides support for the addition of a single
image for a Staff Member<br/>
Allowed formats: JPEG (.jpg or .jpeg), GIF (.gif) and PNG (.png)
</p>
<p> The API supports two different Approaches for manipulating Staff Images
<ul>
<li><a href="http://en.wikipedia.org/wiki/Data_URI_scheme" target="_blank"> Data URI's: </a>
For easier manipulation by Javascript clients etc in supported Browsers.
</li>
<li><a href="http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2">
Multi-part form data:</a>
Images can be uploaded using Multi part forms and downloaded as regular binary files
</li>
<br/>
</div>
</div>
<a id="staff_images_create" name="staff_images_create" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Upload an Image for a Staff (Data URI)</h4>
</div>
<div class="method-example">
<code class="method-declaration">
POST https://DomainName/api/v1/staff/{staffId}/images
</code>
<code class="method-request">
POST staff/1/images
Content-Type: text/plain
Request Body:
data:image/png;base64,iVBORw0KGgoAA
AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0l
EQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6
P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC
</code>
<code class="method-response">
{
"resourceId": 1,
"changes": {},
"resourceIdentifier": "1"
}
</code>
</div>
</div>
<a id="staff_images_create_form" name="staff_images_create_form" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Upload an Image for a Staff Member (Multi-part Form data)</h4>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Mandatory Fields</div></td>
</tr>
<tr class=alt>
<td>file
</td>
</tr>
</table>
<p>
The form should contain a required named body part with the
name "file". <br/> <br/>
If you are using a HTML form, a snippet like
<small> &lt;input type="file" name="file"&gt;&lt;/input&gt; </small>
can be used for uploading the image file
</p>
</div>
<div class="method-example">
<code class="method-declaration">
POST https://DomainName/api/v1/staff/{staffId}/images
</code>
<code class="method-request">
POST staff/1/images
Content-Type: multipart/form-data
Request Body: <i>Not shown</i>
</code>
<code class="method-response">
{
"resourceId": 1,
"changes": {},
"resourceIdentifier": "1"
}
</code>
</div>
</div>
<a id="staff_images_retrieve" name="staff_images_retrieve"
class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Get Staff Image (DATA URI)</h4>
<p>Optional arguments are identical to those of <a href="#client_images_retrieve_binary">Get Staff Image (Binary file)</a></p>
<p>Example Requests:</p>
<div class=apiClick>staff/1/images</div>
<br>
</div>
<div class="method-example">
<code class="method-declaration">
GET https://DomainName/api/v1/staff/{staffId}/images
Accept: text/plain
</code>
<code class="method-response">
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ
bWFnZVJlYWR5ccllPAAAAJ1JREFUeNpi+P//PwMIA4E9EG8E4idQDGLbw+WhiiqA+D8OXAFVAzbp
DxBvB2JLIGaGYkuoGEjOhhFIHAbij0BdPgxYACMj42ogJQpifwBiXSDeC8JIbt4LxSC5DyxQjTeB
+BeaYb+Q5EBOAVutCzMJHUNNPADzzDokiYdAfAmJvwLkGeTgWQfyKZICS6hYBTwc0QL8ORSjBDhA
gAEAOg13B6R/SAgAAAAASUVORK5CYII=
</code>
</div>
</div>
<a id="staff_images_retrieve_binary" name="staff_images_retrieve_binary"
class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Get Staff Image (Binary file)</h4>
<h5>Optional Arguments</h5>
<dl class="argument-list">
<dt>output</dt>
<dd>
String <span>optional</span> one of <span>octet or inline_octet</span>
</dd>
<dd>The query parameter overrides the <span>"Accept" Header</span> and sets the Media Type to "application/octet-stream" <br/>
<span><b>octet :</b></span> Returns the image binary file as an attachment. The <span>Content-Disposition</span> header is set to <span>attachment;filename=somefile.ext</span> <br/>
<span><b>inline_octet :</b></span>The <span>Content-Disposition</span> header is set to <span>inline;filename=somefile.ext</span>
</dd>
<dt>maxWidth</dt>
<dd>
Integer <span>optional</span>
</dd>
<dd>Triggers resizing of the image to the defined width</dd>
<dt>maxHeight</dt>
<dd>
<dd>
Integer <span>optional</span>
</dd>
</dd>
<dd>Triggers resizing of the image to the defined height</dd>
</dl>
</div>
<div class="method-example">
<code class="method-declaration">
GET https://DomainName/api/v1/staff/{staffId}/images
Accept: application/octet-stream
</code>
<code class="method-request">
POST staff/1/images
Accept: application/octet-stream
</code>
<code class="method-response">
<i>Not shown</i>: The corresponding binary (image) file
</code>
</div>
</div>
<a id="staff_images_update" name="staff_images_update" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Update a Staff Image (Data URI)</h4>
</div>
<div class="method-example">
<code class="method-declaration">
PUT https://DomainName/api/v1/staff/{staffId}/images
</code>
<code class="method-request">
PUT staff/1/images
Content-Type: text/plain
Request Body:
data:image/png;base64,iVBORw0KGgoAA
AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0l
EQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6
P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC
</code>
<code class="method-response">
{
"resourceId": 1,
"changes": {},
"resourceIdentifier": "1"
}
</code>
</div>
</div>
<a id="staff_images_update_form" name="staff_images_update_form" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Update a Staff Member Image (Multi-part Form data)</h4>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Mandatory Fields</div></td>
</tr>
<tr class=alt>
<td>file
</td>
</tr>
</table>
<p>
The form should contain a required named body part with the
name "file". <br/> <br/>
If you are using a HTML form, a snippet like
<small> &lt;input type="file" name="file"&gt;&lt;/input&gt; </small>
can be used for uploading the image file
</p>
</div>
<div class="method-example">
<code class="method-declaration">
PUT https://DomainName/api/v1/staff/{staffId}/images
</code>
<code class="method-request">
PUT staff/1/images
Content-Type: multipart/form-data
Request Body: <i>Not shown</i>
</code>
</div>
</div>
<a id="staff_images_delete" name="staff_images_delete" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Delete a Staff Image</h4>
</div>
<div class="method-example">
<code class="method-declaration">
DELETE https://DomainName/api/v1/staff/{staffId}/images
</code>
<code class="method-request">
DELETE staff/1/images
Content-Type: application/json
No Request Body:
</code>
<code class="method-response">
{
"resourceId": 1,
"changes": {},
"resourceIdentifier": "1"
}
</code>
</div>
</div>
<!--Charges section starts here--> <!--Charges section starts here-->
<a id="charges" name="charges" class="old-syle-anchor">&nbsp;</a> <a id="charges" name="charges" class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
@@ -19705,7 +19481,6 @@ Content-Type: application/json
<tr><td class=fielddesc><b>Optional</b>: If provided, used along with <i>lockinPeriodFrequencyType</i> to indicate the length of time that the recurring deposit account is 'locked in' and premature closure is not allowed. e.g. <b>2</b> Months</td></tr> <tr><td class=fielddesc><b>Optional</b>: If provided, used along with <i>lockinPeriodFrequencyType</i> to indicate the length of time that the recurring deposit account is 'locked in' and premature closure is not allowed. e.g. <b>2</b> Months</td></tr>
<tr class=alt><td>lockinPeriodFrequencyType</td></tr> <tr class=alt><td>lockinPeriodFrequencyType</td></tr>
<tr><td class=fielddesc><b>Optional</b>: If provided, used along with <i>lockinPeriodFrequency</i> to indicate the length of time that the recurring deposit account is 'locked in' and premature closure is not allowed. 0=Days, 1=Weeks, 2=Months, 3=Years
e.g. 2 <b>Months</b></td></tr> e.g. 2 <b>Months</b></td></tr>
<tr class=alt><td>recurringDepositFrequency</td></tr> <tr class=alt><td>recurringDepositFrequency</td></tr>
@@ -36498,21 +36273,21 @@ No Request Body:
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td><a href="#staff_images">Staff Images</a></td> <td><a href="#client_images">Staff Images</a></td>
<td>staff/{staffId}/images</td> <td>staff/{staffId}/images</td>
<td><a href="#staff_images_create">Upload an Image for a Staff Member (as DATA URI)</a></td> <td><a href="#client_images_create">Upload an Image for a Staff Member (as DATA URI)</a></td>
<td><a href="#staff_images_retrieve">Get Staff Image (DATA URI)</a></td> <td><a href="#client_images_retrieve">Get Staff Image (DATA URI)</a></td>
<td><a href="#staff_images_update">Update Staff Image (DATA URI)</a></td> <td><a href="#client_images_update">Update Staff Image (DATA URI)</a></td>
<td><a href="#staff_images_delete">Delete Staff Image</a></td> <td><a href="#client_images_delete">Delete Staff Image</a></td>
</tr> </tr>
<tr> <tr>
<td></td> <td></td>
<td></td> <td></td>
<td><a href="#staff_images_create_form"> <td><a href="#client_images_create_form">
Upload an Image for a Staff Member (Multi-part form data)</a> Upload an Image for a Staff Member (Multi-part form data)</a>
</td> </td>
<td><a href="#staff_images_retrieve_binary">Get Staff Image (Binary file)</a></td> <td><a href="#client_images_retrieve_binary">Get Staff Image (Binary file)</a></td>
<td><a href="#staff_images_update_form"> <td><a href="#client_images_update_form">
Update Staff Image (Multi-part form data)</a> Update Staff Image (Multi-part form data)</a>
</td> </td>
<td></td> <td></td>
@@ -1,3 +1,8 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.integrationtests; package org.mifosplatform.integrationtests;
import com.sun.jersey.core.util.Base64; import com.sun.jersey.core.util.Base64;
@@ -1,15 +1,14 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.integrationtests.common; package org.mifosplatform.integrationtests.common;
import com.jayway.restassured.http.ContentType; import org.apache.http.HttpHeaders;
import com.jayway.restassured.specification.RequestSpecification; import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification; import com.jayway.restassured.specification.ResponseSpecification;
import com.sun.jersey.core.util.Base64;
import org.apache.http.HttpHeaders;
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
public class ImageHelper { public class ImageHelper {
@@ -17,40 +16,38 @@ public class ImageHelper {
private static final String IMAGES_URI = "/images"; private static final String IMAGES_URI = "/images";
public static Integer createImageForStaff(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static Integer createImageForStaff(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
Integer staffId) { Integer staffId) {
System.out.println("---------------------------------CREATING AN IMAGE FOR STAFF---------------------------------------------"); System.out.println("---------------------------------CREATING AN IMAGE FOR STAFF---------------------------------------------");
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI+ "?" + Utils.TENANT_IDENTIFIER; String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
return Utils.performServerPost(requestSpec, responseSpec, URL, generateImageAsText(), "resourceId"); return Utils.performServerPost(requestSpec, responseSpec, URL, generateImageAsText(), "resourceId");
} }
public static Integer updateImageForStaff(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static Integer updateImageForStaff(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
Integer staffId) { Integer staffId) {
System.out.println("---------------------------------UPDATING AN IMAGE FOR STAFF---------------------------------------------"); System.out.println("---------------------------------UPDATING AN IMAGE FOR STAFF---------------------------------------------");
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI+ "?" + Utils.TENANT_IDENTIFIER; String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
requestSpec.header(HttpHeaders.CONTENT_TYPE,"mutlipart/form-data");
return Utils.performServerPut(requestSpec, responseSpec, URL, generateImageAsText(), "resourceId"); return Utils.performServerPut(requestSpec, responseSpec, URL, generateImageAsText(), "resourceId");
} }
public static String getStaffImageAsText(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static String getStaffImageAsText(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
Integer staffId){ Integer staffId) {
System.out.println("---------------------------------RETRIEVING STAFF IMAGE---------------------------------------------"); System.out.println("---------------------------------RETRIEVING STAFF IMAGE---------------------------------------------");
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI+ "?" + Utils.TENANT_IDENTIFIER; String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
requestSpec.header(HttpHeaders.ACCEPT,"text/plain"); requestSpec.header(HttpHeaders.ACCEPT, "text/plain");
return Utils.performGetTextResponse(requestSpec, responseSpec, URL); return Utils.performGetTextResponse(requestSpec, responseSpec, URL);
} }
public static byte[] getStaffImageAsBinary(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static byte[] getStaffImageAsBinary(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
Integer staffId){ Integer staffId) {
System.out.println("---------------------------------RETRIEVING STAFF IMAGE---------------------------------------------"); System.out.println("---------------------------------RETRIEVING STAFF IMAGE---------------------------------------------");
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI+ "?" + Utils.TENANT_IDENTIFIER; String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
requestSpec.header(HttpHeaders.ACCEPT,"application/octet-stream"); requestSpec.header(HttpHeaders.ACCEPT, "application/octet-stream");
return Utils.performGetBinaryResponse(requestSpec, responseSpec, URL); return Utils.performGetBinaryResponse(requestSpec, responseSpec, URL);
} }
public static Integer deleteStaffImage(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public static Integer deleteStaffImage(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, Integer staffId) {
Integer staffId){
System.out.println("---------------------------------RETRIEVING STAFF IMAGE---------------------------------------------"); System.out.println("---------------------------------RETRIEVING STAFF IMAGE---------------------------------------------");
String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI+ "?" + Utils.TENANT_IDENTIFIER; String URL = STAFF_IMAGE_URL + staffId + IMAGES_URI + "?" + Utils.TENANT_IDENTIFIER;
return Utils.performServerDelete(requestSpec, responseSpec, URL, "resourceId"); return Utils.performServerDelete(requestSpec, responseSpec, URL, "resourceId");
} }
@@ -60,7 +57,4 @@ public class ImageHelper {
+ "DxBvB2JLIGaGYkuoGEjOhhFIHAbij0BdPgxYACMj42ogJQpifwBiXSDeC8JIbt4LxSC5DyxQjTeB\n" + "DxBvB2JLIGaGYkuoGEjOhhFIHAbij0BdPgxYACMj42ogJQpifwBiXSDeC8JIbt4LxSC5DyxQjTeB\n"
+ "+BeaYb+Q5EBOAVutCzMJHUNNPADzzDokiYdAfAmJvwLkGeTgWQfyKZICS6hYBTwc0QL8ORSjBDhA\n" + "gAEAOg13B6R/SAgAAAAASUVORK5CYII="; + "+BeaYb+Q5EBOAVutCzMJHUNNPADzzDokiYdAfAmJvwLkGeTgWQfyKZICS6hYBTwc0QL8ORSjBDhA\n" + "gAEAOg13B6R/SAgAAAAASUVORK5CYII=";
} }
private static byte[] generateImageAsBinary(){
return Base64.decode(generateImageAsText().split("base64,")[1]);
}
} }
@@ -7,7 +7,16 @@ package org.mifosplatform.infrastructure.documentmanagement.api;
import java.io.InputStream; import java.io.InputStream;
import javax.ws.rs.*; import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.Response.ResponseBuilder;
@@ -19,6 +28,7 @@ import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSeria
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils; import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils;
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils.IMAGE_FILE_EXTENSION; import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils.IMAGE_FILE_EXTENSION;
import org.mifosplatform.infrastructure.documentmanagement.data.ImageData; import org.mifosplatform.infrastructure.documentmanagement.data.ImageData;
import org.mifosplatform.infrastructure.documentmanagement.exception.InvalidEntityTypeForImageManagementException;
import org.mifosplatform.infrastructure.documentmanagement.service.ImageReadPlatformService; import org.mifosplatform.infrastructure.documentmanagement.service.ImageReadPlatformService;
import org.mifosplatform.infrastructure.documentmanagement.service.ImageWritePlatformService; import org.mifosplatform.infrastructure.documentmanagement.service.ImageWritePlatformService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
@@ -32,11 +42,7 @@ import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataBodyPart; import com.sun.jersey.multipart.FormDataBodyPart;
import com.sun.jersey.multipart.FormDataParam; import com.sun.jersey.multipart.FormDataParam;
/** @Path("{entity}/{entityId}/images")
* TODO Vishwas need to change the url to entity/entityId/images to make the
* image management API's generic for other entities like staff etc
**/
@Path("{clients}/{clientId}/images")
@Component @Component
@Scope("singleton") @Scope("singleton")
public class ImagesApiResource { public class ImagesApiResource {
@@ -61,17 +67,17 @@ public class ImagesApiResource {
@POST @POST
@Consumes({ MediaType.MULTIPART_FORM_DATA }) @Consumes({ MediaType.MULTIPART_FORM_DATA })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String addNewClientImage(@PathParam("clients") final String clientName, @PathParam("clientId") final Long clientId, public String addNewClientImage(@PathParam("entity") final String entityName, @PathParam("entityId") final Long entityId,
@HeaderParam("Content-Length") final Long fileSize, @FormDataParam("file") final InputStream inputStream, @HeaderParam("Content-Length") final Long fileSize, @FormDataParam("file") final InputStream inputStream,
@FormDataParam("file") final FormDataContentDisposition fileDetails, @FormDataParam("file") final FormDataBodyPart bodyPart) { @FormDataParam("file") final FormDataContentDisposition fileDetails, @FormDataParam("file") final FormDataBodyPart bodyPart) {
validateEntityTypeforImage(entityName);
// TODO: vishwas might need more advances validation (like reading magic // TODO: vishwas might need more advances validation (like reading magic
// number) for handling malicious clients // number) for handling malicious clients
// and clients not setting mime type // and clients not setting mime type
ContentRepositoryUtils.validateClientImageNotEmpty(fileDetails.getFileName()); ContentRepositoryUtils.validateClientImageNotEmpty(fileDetails.getFileName());
ContentRepositoryUtils.validateImageMimeType(bodyPart.getMediaType().toString()); ContentRepositoryUtils.validateImageMimeType(bodyPart.getMediaType().toString());
final CommandProcessingResult result = this.imageWritePlatformService.saveOrUpdateImage(clientName, clientId, final CommandProcessingResult result = this.imageWritePlatformService.saveOrUpdateImage(entityName, entityId,
fileDetails.getFileName(), inputStream, fileSize); fileDetails.getFileName(), inputStream, fileSize);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
@@ -83,12 +89,12 @@ public class ImagesApiResource {
@POST @POST
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) @Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String addNewClientImage(@PathParam("clients") final String clientName, @PathParam("clientId") final Long clientId, public String addNewClientImage(@PathParam("entity") final String entityName, @PathParam("entityId") final Long entityId,
final String jsonRequestBody) { final String jsonRequestBody) {
validateEntityTypeforImage(entityName);
final Base64EncodedImage base64EncodedImage = ContentRepositoryUtils.extractImageFromDataURL(jsonRequestBody); final Base64EncodedImage base64EncodedImage = ContentRepositoryUtils.extractImageFromDataURL(jsonRequestBody);
final CommandProcessingResult result = this.imageWritePlatformService.saveOrUpdateImage(clientName, clientId, base64EncodedImage); final CommandProcessingResult result = this.imageWritePlatformService.saveOrUpdateImage(entityName, entityId, base64EncodedImage);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@@ -99,15 +105,20 @@ public class ImagesApiResource {
@GET @GET
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) @Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.TEXT_PLAIN }) @Produces({ MediaType.TEXT_PLAIN })
public Response retrieveImage(@PathParam("clients") final String clientName, @PathParam("clientId") final Long clientId, public Response retrieveImage(@PathParam("entity") final String entityName, @PathParam("entityId") final Long entityId,
@QueryParam("maxWidth") final Integer maxWidth, @QueryParam("maxHeight") final Integer maxHeight, @QueryParam("maxWidth") final Integer maxWidth, @QueryParam("maxHeight") final Integer maxHeight,
@QueryParam("output") final String output) { @QueryParam("output") final String output) {
if (output != null && (output.equals("octet") || output.equals("inline_octet"))) { return downloadClientImage(clientName, clientId, validateEntityTypeforImage(entityName);
if (ENTITY_TYPE_FOR_IMAGES.CLIENTS.toString().equalsIgnoreCase(entityName)) {
this.context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
} else if (ENTITY_TYPE_FOR_IMAGES.STAFF.toString().equalsIgnoreCase(entityName)) {
this.context.authenticatedUser().validateHasReadPermission("STAFFIMAGE");
}
if (output != null && (output.equals("octet") || output.equals("inline_octet"))) { return downloadClientImage(entityName, entityId,
maxWidth, maxHeight, output); } maxWidth, maxHeight, output); }
this.context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE"); final ImageData imageData = this.imageReadPlatformService.retrieveImage(entityName, entityId);
final ImageData imageData = this.imageReadPlatformService.retrieveImage(clientName, clientId);
// TODO: Need a better way of determining image type // TODO: Need a better way of determining image type
String imageDataURISuffix = ContentRepositoryUtils.IMAGE_DATA_URI_SUFFIX.JPEG.getValue(); String imageDataURISuffix = ContentRepositoryUtils.IMAGE_DATA_URI_SUFFIX.JPEG.getValue();
@@ -124,12 +135,17 @@ public class ImagesApiResource {
@GET @GET
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_OCTET_STREAM }) @Produces({ MediaType.APPLICATION_OCTET_STREAM })
public Response downloadClientImage(@PathParam("clients") final String clientName, @PathParam("clientId") final Long clientId, public Response downloadClientImage(@PathParam("entity") final String entityName, @PathParam("entityId") final Long entityId,
@QueryParam("maxWidth") final Integer maxWidth, @QueryParam("maxHeight") final Integer maxHeight, @QueryParam("maxWidth") final Integer maxWidth, @QueryParam("maxHeight") final Integer maxHeight,
@QueryParam("output") String output) { @QueryParam("output") String output) {
validateEntityTypeforImage(entityName);
if (ENTITY_TYPE_FOR_IMAGES.CLIENTS.toString().equalsIgnoreCase(entityName)) {
this.context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE");
} else if (ENTITY_TYPE_FOR_IMAGES.STAFF.toString().equalsIgnoreCase(entityName)) {
this.context.authenticatedUser().validateHasReadPermission("STAFFIMAGE");
}
this.context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE"); final ImageData imageData = this.imageReadPlatformService.retrieveImage(entityName, entityId);
final ImageData imageData = this.imageReadPlatformService.retrieveImage(clientName, clientId);
final ResponseBuilder response = Response.ok(imageData.getContentOfSize(maxWidth, maxHeight)); final ResponseBuilder response = Response.ok(imageData.getContentOfSize(maxWidth, maxHeight));
String dispositionType = "inline_octet".equals(output) ? "inline" : "attachment"; String dispositionType = "inline_octet".equals(output) ? "inline" : "attachment";
@@ -149,10 +165,10 @@ public class ImagesApiResource {
@PUT @PUT
@Consumes({ MediaType.MULTIPART_FORM_DATA }) @Consumes({ MediaType.MULTIPART_FORM_DATA })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String updateClientImage(@PathParam("clients") final String clientName, @PathParam("clientId") final Long clientId, public String updateClientImage(@PathParam("entity") final String entityName, @PathParam("entityId") final Long entityId,
@HeaderParam("Content-Length") final Long fileSize, @FormDataParam("file") final InputStream inputStream, @HeaderParam("Content-Length") final Long fileSize, @FormDataParam("file") final InputStream inputStream,
@FormDataParam("file") final FormDataContentDisposition fileDetails, @FormDataParam("file") final FormDataBodyPart bodyPart) { @FormDataParam("file") final FormDataContentDisposition fileDetails, @FormDataParam("file") final FormDataBodyPart bodyPart) {
return addNewClientImage(clientName, clientId, fileSize, inputStream, fileDetails, bodyPart); return addNewClientImage(entityName, entityId, fileSize, inputStream, fileDetails, bodyPart);
} }
/** /**
@@ -164,17 +180,39 @@ public class ImagesApiResource {
@PUT @PUT
@Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) @Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String updateClientImage(@PathParam("clients") final String clientName, @PathParam("clientId") final Long clientId, public String updateClientImage(@PathParam("entity") final String entityName, @PathParam("entityId") final Long entityId,
final String jsonRequestBody) { final String jsonRequestBody) {
return addNewClientImage(clientName, clientId, jsonRequestBody); return addNewClientImage(entityName, entityId, jsonRequestBody);
} }
@DELETE @DELETE
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String deleteClientImage(@PathParam("clients") final String clientName, @PathParam("clientId") final Long clientId) { public String deleteClientImage(@PathParam("entity") final String entityName, @PathParam("entityId") final Long entityId) {
this.imageWritePlatformService.deleteImage(clientName, clientId); validateEntityTypeforImage(entityName);
return this.toApiJsonSerializer.serialize(new CommandProcessingResult(clientId)); this.imageWritePlatformService.deleteImage(entityName, entityId);
return this.toApiJsonSerializer.serialize(new CommandProcessingResult(entityId));
}
/*** Entities for document Management **/
public static enum ENTITY_TYPE_FOR_IMAGES {
STAFF, CLIENTS;
@Override
public String toString() {
return name().toString().toLowerCase();
}
}
private void validateEntityTypeforImage(final String entityName) {
if (!checkValidEntityType(entityName)) { throw new InvalidEntityTypeForImageManagementException(entityName); }
}
private static boolean checkValidEntityType(final String entityType) {
for (final ENTITY_TYPE_FOR_IMAGES entities : ENTITY_TYPE_FOR_IMAGES.values()) {
if (entities.name().equalsIgnoreCase(entityType)) { return true; }
}
return false;
} }
} }
@@ -0,0 +1,18 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.infrastructure.documentmanagement.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
/**
* Runtime exception for invalid image types
*/
public class InvalidEntityTypeForImageManagementException extends AbstractPlatformResourceNotFoundException {
public InvalidEntityTypeForImageManagementException(String imageType) {
super("error.imagemanagement.entitytype.invalid", "Image Management is not support for the Entity Type: " + imageType);
}
}
@@ -1,13 +0,0 @@
package org.mifosplatform.infrastructure.documentmanagement.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
/**
* Runtime exception for invalid image types
*/
public class InvalidImageTypeException extends AbstractPlatformResourceNotFoundException {
public InvalidImageTypeException(String imageType) {
super("error.documentmanagement.imagetype.invalid", "Image type not supported: " + imageType, imageType);
}
}
@@ -9,6 +9,6 @@ import org.mifosplatform.infrastructure.documentmanagement.data.ImageData;
public interface ImageReadPlatformService { public interface ImageReadPlatformService {
ImageData retrieveImage(String clientName, Long clientId); ImageData retrieveImage(String entityType, Long entityId);
} }
@@ -10,6 +10,7 @@ import java.sql.SQLException;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.RoutingDataSource; import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
import org.mifosplatform.infrastructure.documentmanagement.api.ImagesApiResource.ENTITY_TYPE_FOR_IMAGES;
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepository; import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepository;
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory; import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory;
import org.mifosplatform.infrastructure.documentmanagement.data.ImageData; import org.mifosplatform.infrastructure.documentmanagement.data.ImageData;
@@ -30,13 +31,12 @@ public class ImageReadPlatformServiceImpl implements ImageReadPlatformService {
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final ContentRepositoryFactory contentRepositoryFactory; private final ContentRepositoryFactory contentRepositoryFactory;
private final ClientRepositoryWrapper clientRepositoryWrapper; private final ClientRepositoryWrapper clientRepositoryWrapper;
private final StaffRepositoryWrapper staffRepositoryWrapper; private final StaffRepositoryWrapper staffRepositoryWrapper;
@Autowired @Autowired
public ImageReadPlatformServiceImpl(final RoutingDataSource dataSource, final ContentRepositoryFactory documentStoreFactory, public ImageReadPlatformServiceImpl(final RoutingDataSource dataSource, final ContentRepositoryFactory documentStoreFactory,
final ClientRepositoryWrapper clientRepositoryWrapper, final ClientRepositoryWrapper clientRepositoryWrapper, StaffRepositoryWrapper staffRepositoryWrapper) {
StaffRepositoryWrapper staffRepositoryWrapper) { this.staffRepositoryWrapper = staffRepositoryWrapper;
this.staffRepositoryWrapper = staffRepositoryWrapper;
this.jdbcTemplate = new JdbcTemplate(dataSource); this.jdbcTemplate = new JdbcTemplate(dataSource);
this.contentRepositoryFactory = documentStoreFactory; this.contentRepositoryFactory = documentStoreFactory;
this.clientRepositoryWrapper = clientRepositoryWrapper; this.clientRepositoryWrapper = clientRepositoryWrapper;
@@ -50,11 +50,11 @@ public class ImageReadPlatformServiceImpl implements ImageReadPlatformService {
this.entityDisplayName = entityDisplayName; this.entityDisplayName = entityDisplayName;
} }
public String schema(String clientName) { public String schema(String entityType) {
StringBuilder builder = new StringBuilder("image.id as id, image.location as location, image.storage_type_enum as storageType "); StringBuilder builder = new StringBuilder("image.id as id, image.location as location, image.storage_type_enum as storageType ");
if (ImageWritePlatformServiceJpaRepositoryImpl.IMAGE_TYPE.CLIENTS.toString().equals(clientName)) { if (ENTITY_TYPE_FOR_IMAGES.CLIENTS.toString().equalsIgnoreCase(entityType)) {
builder.append(" from m_image image , m_client client " + " where client.image_id = image.id and client.id=?"); builder.append(" from m_image image , m_client client " + " where client.image_id = image.id and client.id=?");
} else if (ImageWritePlatformServiceJpaRepositoryImpl.IMAGE_TYPE.STAFF.toString().equals(clientName)) { } else if (ENTITY_TYPE_FOR_IMAGES.STAFF.toString().equalsIgnoreCase(entityType)) {
builder.append("from m_image image , m_staff staff " + " where staff.image_id = image.id and staff.id=?"); builder.append("from m_image image , m_staff staff " + " where staff.image_id = image.id and staff.id=?");
} }
return builder.toString(); return builder.toString();
@@ -71,34 +71,30 @@ public class ImageReadPlatformServiceImpl implements ImageReadPlatformService {
} }
@Override @Override
public ImageData retrieveImage(String clientName, final Long clientId) { public ImageData retrieveImage(String entityType, final Long entityId) {
try { try {
Object owner; Object owner;
String displayName = null; String displayName = null;
if (ImageWritePlatformServiceJpaRepositoryImpl.IMAGE_TYPE.CLIENTS if (ENTITY_TYPE_FOR_IMAGES.CLIENTS.toString().equalsIgnoreCase(entityType)) {
.toString().equals(clientName)) { owner = this.clientRepositoryWrapper.findOneWithNotFoundDetection(entityId);
owner = this.clientRepositoryWrapper displayName = ((Client) owner).getDisplayName();
.findOneWithNotFoundDetection(clientId); } else if (ENTITY_TYPE_FOR_IMAGES.STAFF.toString().equalsIgnoreCase(entityType)) {
displayName = ((Client) owner).getDisplayName(); owner = this.staffRepositoryWrapper.findOneWithNotFoundDetection(entityId);
} else if (ImageWritePlatformServiceJpaRepositoryImpl.IMAGE_TYPE.STAFF displayName = ((Staff) owner).displayName();
.toString().equals(clientName)) { }
owner = this.staffRepositoryWrapper final ImageMapper imageMapper = new ImageMapper(displayName);
.findOneWithNotFoundDetection(clientId);
displayName = ((Staff) owner).displayName();
}
final ImageMapper imageMapper = new ImageMapper(displayName);
final String sql = "select " + imageMapper.schema(clientName); final String sql = "select " + imageMapper.schema(entityType);
final ImageData imageData = this.jdbcTemplate.queryForObject(sql, imageMapper, new Object[] { clientId }); final ImageData imageData = this.jdbcTemplate.queryForObject(sql, imageMapper, new Object[] { entityId });
final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(imageData.storageType()); final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(imageData.storageType());
final ImageData result = contentRepository.fetchImage(imageData); final ImageData result = contentRepository.fetchImage(imageData);
if (result.getContent() == null) { throw new ImageNotFoundException("clients", clientId); } if (result.getContent() == null) { throw new ImageNotFoundException(entityType, entityId); }
return result; return result;
} catch (final EmptyResultDataAccessException e) { } catch (final EmptyResultDataAccessException e) {
throw new ImageNotFoundException("clients", clientId); throw new ImageNotFoundException("clients", entityId);
} }
} }
} }
@@ -13,12 +13,12 @@ import org.springframework.security.access.prepost.PreAuthorize;
public interface ImageWritePlatformService { public interface ImageWritePlatformService {
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE')") @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE','CREATE_STAFFIMAGE')")
CommandProcessingResult saveOrUpdateImage(String clientName, Long clientId, String imageName, InputStream inputStream, Long fileSize); CommandProcessingResult saveOrUpdateImage(String entityName, Long entityId, String imageName, InputStream inputStream, Long fileSize);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE')") @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE','CREATE_STAFFIMAGE')")
CommandProcessingResult saveOrUpdateImage(String clientName, Long clientId, Base64EncodedImage encodedImage); CommandProcessingResult saveOrUpdateImage(String entityName, Long entityId, Base64EncodedImage encodedImage);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_CLIENTIMAGE')") @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_CLIENTIMAGE','DELETE_STAFFIMAGE')")
CommandProcessingResult deleteImage(String clientName, Long clientId); CommandProcessingResult deleteImage(String entityName, Long entityId);
} }
@@ -9,12 +9,12 @@ import java.io.InputStream;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage; import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
import org.mifosplatform.infrastructure.documentmanagement.api.ImagesApiResource.ENTITY_TYPE_FOR_IMAGES;
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepository; import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepository;
import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory; import org.mifosplatform.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory;
import org.mifosplatform.infrastructure.documentmanagement.domain.Image; import org.mifosplatform.infrastructure.documentmanagement.domain.Image;
import org.mifosplatform.infrastructure.documentmanagement.domain.ImageRepository; import org.mifosplatform.infrastructure.documentmanagement.domain.ImageRepository;
import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType; import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType;
import org.mifosplatform.infrastructure.documentmanagement.exception.InvalidImageTypeException;
import org.mifosplatform.organisation.staff.domain.Staff; import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper; import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper;
import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.Client;
@@ -33,7 +33,8 @@ public class ImageWritePlatformServiceJpaRepositoryImpl implements ImageWritePla
@Autowired @Autowired
public ImageWritePlatformServiceJpaRepositoryImpl(final ContentRepositoryFactory documentStoreFactory, public ImageWritePlatformServiceJpaRepositoryImpl(final ContentRepositoryFactory documentStoreFactory,
final ClientRepositoryWrapper clientRepositoryWrapper, final ImageRepository imageRepository, StaffRepositoryWrapper staffRepositoryWrapper) { final ClientRepositoryWrapper clientRepositoryWrapper, final ImageRepository imageRepository,
StaffRepositoryWrapper staffRepositoryWrapper) {
this.contentRepositoryFactory = documentStoreFactory; this.contentRepositoryFactory = documentStoreFactory;
this.clientRepositoryWrapper = clientRepositoryWrapper; this.clientRepositoryWrapper = clientRepositoryWrapper;
this.imageRepository = imageRepository; this.imageRepository = imageRepository;
@@ -42,15 +43,9 @@ public class ImageWritePlatformServiceJpaRepositoryImpl implements ImageWritePla
@Transactional @Transactional
@Override @Override
public CommandProcessingResult saveOrUpdateImage(String clientName, final Long clientId, final String imageName, final InputStream inputStream, public CommandProcessingResult saveOrUpdateImage(String entityName, final Long clientId, final String imageName,
final Long fileSize) { final InputStream inputStream, final Long fileSize) {
Object owner = null; Object owner = deletePreviousImage(entityName, clientId);
if (IMAGE_TYPE.CLIENTS.toString().equals(clientName)){
owner =this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
} else if (IMAGE_TYPE.STAFF.toString().equals(clientName)) {
owner = this.staffRepositoryWrapper.findOneWithNotFoundDetection(clientId);
}
deletePreviousImage(owner);
final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(); final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository();
final String imageLocation = contentRepository.saveImage(inputStream, clientId, imageName, fileSize); final String imageLocation = contentRepository.saveImage(inputStream, clientId, imageName, fileSize);
@@ -59,15 +54,8 @@ public class ImageWritePlatformServiceJpaRepositoryImpl implements ImageWritePla
@Transactional @Transactional
@Override @Override
public CommandProcessingResult saveOrUpdateImage(String clientName, final Long clientId, final Base64EncodedImage encodedImage) { public CommandProcessingResult saveOrUpdateImage(String entityName, final Long clientId, final Base64EncodedImage encodedImage) {
Object owner = null; Object owner = deletePreviousImage(entityName, clientId);
if (IMAGE_TYPE.CLIENTS.toString().equals(clientName)){
owner =this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
} else if (IMAGE_TYPE.STAFF.toString().equals(clientName)) {
owner = this.staffRepositoryWrapper.findOneWithNotFoundDetection(clientId);
}
deletePreviousImage(owner);
validateImageType(clientName);
final ContentRepository contenRepository = this.contentRepositoryFactory.getRepository(); final ContentRepository contenRepository = this.contentRepositoryFactory.getRepository();
final String imageLocation = contenRepository.saveImage(encodedImage, clientId, "image"); final String imageLocation = contenRepository.saveImage(encodedImage, clientId, "image");
@@ -77,18 +65,17 @@ public class ImageWritePlatformServiceJpaRepositoryImpl implements ImageWritePla
@Transactional @Transactional
@Override @Override
public CommandProcessingResult deleteImage(String clientName, final Long clientId) { public CommandProcessingResult deleteImage(String entityName, final Long clientId) {
Object owner = null; Object owner = null;
Image image = null; Image image = null;
if (IMAGE_TYPE.CLIENTS.toString().equals(clientName)){ if (ENTITY_TYPE_FOR_IMAGES.CLIENTS.toString().equals(entityName)) {
owner =this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId); owner = this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
Client client = (Client) owner; Client client = (Client) owner;
image = client.getImage(); image = client.getImage();
client.setImage(null); client.setImage(null);
this.clientRepositoryWrapper.save(client); this.clientRepositoryWrapper.save(client);
} else if (IMAGE_TYPE.STAFF.toString().equals(clientName)) { } else if (ENTITY_TYPE_FOR_IMAGES.STAFF.toString().equals(entityName)) {
owner = this.staffRepositoryWrapper.findOneWithNotFoundDetection(clientId); owner = this.staffRepositoryWrapper.findOneWithNotFoundDetection(clientId);
Staff staff = (Staff) owner; Staff staff = (Staff) owner;
image = staff.getImage(); image = staff.getImage();
@@ -107,36 +94,42 @@ public class ImageWritePlatformServiceJpaRepositoryImpl implements ImageWritePla
return new CommandProcessingResult(clientId); return new CommandProcessingResult(clientId);
} }
private void deletePreviousImage(final Object owner) { /**
* @param entityName
* @param entityId
* @return
*/
private Object deletePreviousImage(String entityName, final Long entityId) {
Object owner = null;
Image image = null; Image image = null;
Long clientId=null; if (ENTITY_TYPE_FOR_IMAGES.CLIENTS.toString().equals(entityName)) {
if (owner instanceof Client){ Client client = this.clientRepositoryWrapper.findOneWithNotFoundDetection(entityId);
Client client = (Client) owner;
image = client.getImage(); image = client.getImage();
clientId = client.getId(); owner = client;
} else if (owner instanceof Staff){ } else if (ENTITY_TYPE_FOR_IMAGES.STAFF.toString().equals(entityName)) {
Staff staff = (Staff) owner; Staff staff = this.staffRepositoryWrapper.findOneWithNotFoundDetection(entityId);
image = staff.getImage(); image = staff.getImage();
clientId = staff.getId(); owner = staff;
} }
if (image != null) { if (image != null) {
final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(StorageType.fromInt(image final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(StorageType.fromInt(image
.getStorageType())); .getStorageType()));
contentRepository.deleteImage(clientId, image.getLocation()); contentRepository.deleteImage(entityId, image.getLocation());
} }
return owner;
} }
private CommandProcessingResult updateImage(final Object owner, final String imageLocation, final StorageType storageType) { private CommandProcessingResult updateImage(final Object owner, final String imageLocation, final StorageType storageType) {
Image image = null; Image image = null;
Long clientId=null; Long clientId = null;
if (owner instanceof Client){ if (owner instanceof Client) {
Client client = (Client) owner; Client client = (Client) owner;
image = client.getImage(); image = client.getImage();
clientId = client.getId(); clientId = client.getId();
image = createImage(image, imageLocation, storageType); image = createImage(image, imageLocation, storageType);
client.setImage(image); client.setImage(image);
this.clientRepositoryWrapper.save(client); this.clientRepositoryWrapper.save(client);
} else if (owner instanceof Staff){ } else if (owner instanceof Staff) {
Staff staff = (Staff) owner; Staff staff = (Staff) owner;
image = staff.getImage(); image = staff.getImage();
clientId = staff.getId(); clientId = staff.getId();
@@ -159,25 +152,4 @@ public class ImageWritePlatformServiceJpaRepositoryImpl implements ImageWritePla
return image; return image;
} }
private void validateImageType(final String clientName) {
if (!checkValidEntityType(clientName)) { throw new InvalidImageTypeException(
clientName); }
}
private static boolean checkValidEntityType(final String entityType) {
for (final IMAGE_TYPE entities : IMAGE_TYPE.values()) {
if (entities.name().equalsIgnoreCase(entityType)) { return true; }
}
return false;
}
/*** Entities for document Management **/
public static enum IMAGE_TYPE {
STAFF,CLIENTS;
@Override
public String toString() {
return name().toString().toLowerCase();
}}
} }
@@ -19,4 +19,10 @@ set report_parameter_name='branch'
where report_id=(select stretchy_report.id from stretchy_report where report_name='GeneralLedgerReport') where report_id=(select stretchy_report.id from stretchy_report where report_name='GeneralLedgerReport')
and parameter_id=(select p.id from stretchy_parameter p where parameter_name='OfficeIdSelectOne'); and parameter_id=(select p.id from stretchy_parameter p where parameter_name='OfficeIdSelectOne');
INSERT INTO `m_permission` VALUES ('report', 'READ_GeneralLedgerReport', 'GeneralLedgerReport', 'READ', 0); INSERT INTO `m_permission` (
`grouping` ,
`code` ,
`entity_name` ,
`action_name` ,
`can_maker_checker`
) VALUES ('report', 'READ_General Ledger Report', 'General Ledger Report', 'READ', 0);
@@ -1,3 +1,16 @@
ALTER TABLE `m_staff` ALTER TABLE `m_staff`
ADD COLUMN `image_id` BIGINT(20) NULL, ADD COLUMN `image_id` BIGINT(20) NULL,
ADD CONSTRAINT `FK_m_staff_m_image` FOREIGN KEY (`image_id`) REFERENCES `m_image` (`id`); ADD CONSTRAINT `FK_m_staff_m_image` FOREIGN KEY (`image_id`) REFERENCES `m_image` (`id`);
INSERT INTO m_permission (
grouping ,
code ,
entity_name ,
action_name ,
can_maker_checker
) VALUES
('portfolio', 'READ_STAFFIMAGE', 'STAFFIMAGE', 'READ', '0'),
('portfolio', 'CREATE_STAFFIMAGE', 'STAFFIMAGE', 'CREATE', '1'),
('portfolio', 'CREATE_STAFFIMAGE_CHECKER', 'STAFFIMAGE', 'CREATE', '0'),
('portfolio', 'DELETE_STAFFIMAGE', 'STAFFIMAGE', 'DELETE', '1'),
('portfolio', 'DELETE_STAFFIMAGE_CHECKER', 'STAFFIMAGE', 'DELETE', '0');