1010import com .sap .cds .feature .attachments .generated .cds4j .sap .attachments .Attachments ;
1111import com .sap .cds .feature .attachments .handler .applicationservice .modifyevents .ModifyAttachmentEvent ;
1212import com .sap .cds .feature .attachments .handler .applicationservice .modifyevents .ModifyAttachmentEventFactory ;
13+ import com .sap .cds .feature .attachments .handler .applicationservice .readhelper .CountingInputStream ;
1314import com .sap .cds .feature .attachments .handler .common .ApplicationHandlerHelper ;
1415import com .sap .cds .ql .cqn .Path ;
1516import com .sap .cds .reflect .CdsEntity ;
2324
2425public final class ModifyApplicationHandlerHelper {
2526
26- private static final Filter VALMAX_FILTER =
27- (path , element , type ) ->
28- element .getName ().contentEquals ("content" )
29- && element .findAnnotation ("Validation.Maximum" ).isPresent ();
27+ private static final Filter VALMAX_FILTER = (path , element , type ) -> element .getName ().contentEquals ("content" )
28+ && element .findAnnotation ("Validation.Maximum" ).isPresent ();
3029
3130 /**
3231 * Handles attachments for entities.
3332 *
34- * @param entity the {@link CdsEntity entity} to handle attachments for
35- * @param data the given list of {@link CdsData data}
33+ * @param entity the {@link CdsEntity entity} to handle attachments
34+ * for
35+ * @param data the given list of {@link CdsData data}
3636 * @param existingAttachments the given list of existing {@link CdsData data}
37- * @param eventFactory the {@link ModifyAttachmentEventFactory} to create the corresponding event
38- * @param eventContext the current {@link EventContext}
37+ * @param eventFactory the {@link ModifyAttachmentEventFactory} to create
38+ * the corresponding event
39+ * @param eventContext the current {@link EventContext}
3940 */
4041 public static void handleAttachmentForEntities (
4142 CdsEntity entity ,
4243 List <CdsData > data ,
4344 List <Attachments > existingAttachments ,
4445 ModifyAttachmentEventFactory eventFactory ,
4546 EventContext eventContext ) {
46- Converter converter =
47- (path , element , value ) ->
48- handleAttachmentForEntity (
49- existingAttachments , eventFactory , eventContext , path , (InputStream ) value );
47+ Converter converter = (path , element , value ) -> handleAttachmentForEntity (
48+ existingAttachments , eventFactory , eventContext , path , (InputStream ) value );
5049
5150 CdsDataProcessor .create ()
5251 .addConverter (ApplicationHandlerHelper .MEDIA_CONTENT_FILTER , converter )
@@ -56,11 +55,13 @@ public static void handleAttachmentForEntities(
5655 /**
5756 * Handles attachments for a single entity.
5857 *
59- * @param existingAttachments the list of existing {@link Attachments} to check against
60- * @param eventFactory the {@link ModifyAttachmentEventFactory} to create the corresponding event
61- * @param eventContext the current {@link EventContext}
62- * @param path the {@link Path} of the attachment
63- * @param content the content of the attachment
58+ * @param existingAttachments the list of existing {@link Attachments} to check
59+ * against
60+ * @param eventFactory the {@link ModifyAttachmentEventFactory} to create
61+ * the corresponding event
62+ * @param eventContext the current {@link EventContext}
63+ * @param path the {@link Path} of the attachment
64+ * @param content the content of the attachment
6465 * @return the processed content as an {@link InputStream}
6566 */
6667 public static InputStream handleAttachmentForEntity (
@@ -74,28 +75,15 @@ public static InputStream handleAttachmentForEntity(
7475 Attachments attachment = getExistingAttachment (keys , existingAttachments );
7576 String contentId = (String ) path .target ().values ().get (Attachments .CONTENT_ID );
7677 String contentLength = eventContext .getParameterInfo ().getHeader ("Content-Length" );
77- String maxSizeStr = getValMaxValue (path .target ().entity (), existingAttachments );
78-
79- if (maxSizeStr != null && content != null ) {
80- try {
81- long maxSize = FileSizeUtils .parseFileSizeToBytes (maxSizeStr );
82- if (contentLength != null && Long .parseLong (contentLength ) > maxSize ) {
83- throw new RuntimeException ("File size exceeds the maximum allowed size of " + maxSizeStr );
84- }
85- } catch (ArithmeticException e ) {
86- throw new ServiceException ("Maximum file size value is too large" , e );
87- } catch (IllegalArgumentException e ) {
88- throw new ServiceException (ErrorStatuses .BAD_REQUEST , "Failed to process attachment size" );
89- } catch (RuntimeException e ) {
90- throw new ServiceException (ExtendedErrorStatuses .CONTENT_TOO_LARGE , "AttachmentSizeExceeded" , maxSizeStr );
91- }
92- }
78+
79+ InputStream wrappedContent = wrapWithCountingStream (content , path .target ().entity (), existingAttachments ,
80+ contentLength );
9381
9482 // for the current request find the event to process
95- ModifyAttachmentEvent eventToProcess = eventFactory .getEvent (content , contentId , attachment );
83+ ModifyAttachmentEvent eventToProcess = eventFactory .getEvent (wrappedContent , contentId , attachment );
9684
9785 // process the event
98- return eventToProcess .processEvent (path , content , attachment , eventContext );
86+ return eventToProcess .processEvent (path , wrappedContent , attachment , eventContext );
9987 }
10088
10189 private static String getValMaxValue (CdsEntity entity , List <? extends CdsData > data ) {
@@ -120,6 +108,27 @@ private static Attachments getExistingAttachment(
120108 .orElse (Attachments .create ());
121109 }
122110
111+ private static InputStream wrapWithCountingStream (
112+ InputStream content , CdsEntity entity , List <? extends CdsData > data , String contentLength ) {
113+ String maxSizeStr = getValMaxValue (entity , data );
114+
115+ if (maxSizeStr != null && content != null ) {
116+ try {
117+ long maxSize = FileSizeUtils .parseFileSizeToBytes (maxSizeStr );
118+ // if (contentLength != null && Long.parseLong(contentLength) > maxSize) {
119+ // throw new RuntimeException();
120+ // }
121+ return new CountingInputStream (content , maxSize );
122+ } catch (ArithmeticException e ) {
123+ throw new ServiceException ("Maximum file size value is too large" , e );
124+ } catch (RuntimeException e ) {
125+ throw new ServiceException (
126+ ExtendedErrorStatuses .CONTENT_TOO_LARGE , "AttachmentSizeExceeded" , maxSizeStr );
127+ }
128+ }
129+ return content ;
130+ }
131+
123132 private ModifyApplicationHandlerHelper () {
124133 // avoid instantiation
125134 }
0 commit comments