Odata File Download / get_stream method doesnt work - odata

I have an oData service for File Download functionality. I have to include $value parameter to oData call to trigger GET_Stream at backend.
I see with an external breakpoint on get_stream method, that the method is triggered. But the file download doesn't work. I get a HTTP response 200 which means it is all OK but I don't see any data or row of information. The response in /IWFND/GW_CLIENT is empty.
So I debug and see that at the end of the get_stream method there is a parameter changing with these lines:
COPY_DATA_TO_REF(
EXPORTING IS_DATA = LS_STREAM
CHANGING CR_DATA = ER_STREAM)
In ls_stream there should be two columns (column1 and column2).
One of the columns is set and the other is empty. No matter what value I give to column2, it is still empty. Maybe I don't get any information at /IWFND/GW_CLIENT request because the parameter column2 is empty? Can you give me a suggestion?
My redefined methods are:
_DPC_EXT:
/IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_STREAM
ATTACHMENTSET_GET_ENTITYSET
_MPC_EXT:
DEFINE

I'm not sure what are these two components column1 and column2 you are referring to...
To return a PDF, you must define the entity type as being "Media" (checkbox), and transfer the PDF through the type /iwbep/if_mgw_appl_types=>ty_s_media_resource (components value of type XSTRING and mime_type).
More information in SAP Library > SAP Gateway Foundation Developer Guide > Media Links.
Example:
OData service ZGETPDF, with entity type File of type "Media" (and entity set FileSet)
URL to query the PDF: https://server.company.com:44322/sap/opu/odata/sap/ZGETPDF_SRV/FileSet('notused.pdf')/$value
ZCL_ZGETPDF_DPC_EXT class:
GET_STREAM method:
METHOD /iwbep/if_mgw_appl_srv_runtime~get_stream.
DATA: ls_stream TYPE /iwbep/if_mgw_appl_types=>ty_s_media_resource.
ls_stream-value = get_dummy_pdf( ).
ls_stream-mime_type = 'application/pdf'.
copy_data_to_ref( EXPORTING is_data = ls_stream
CHANGING cr_data = er_stream ).
ENDMETHOD.
Code to get a dummy PDF (any PDF, just for demo):
METHODS get_dummy_pdf RETURNING VALUE(result) TYPE xstring.
...
METHOD get_dummy_pdf.
" PDF from http://www.tagg.org/pdftest.pdf University of Liverpool
DATA(base64_string) =
'JVBERi0xLjIgDQol4uPP0w0KIA0KOSAwIG9iag0KPDwNCi9MZW5ndGggMTAgMCBSDQovRmlsdGVyIC9GbGF0ZURlY29kZSANCj4+'
&& 'DQpzdHJlYW0NCkiJzZDRSsMwFIafIO/we6eyZuckTZPtbtIWBi0UjYKQGxFbJmpliuLb26QM8X6CJBfJyf99ycmFF6xJagWrrMxz'
&& 'wJeCEMd+gFjWBC1dLPeCJFkbl/fTKfwnTqt1CK0xIZyEwFYZ2T+fwT8KnmIxUmJinNKJyUiyW7mZVEQ6I54m2K3ZzFiupvgPaee7'
&& 'JHFuZqyDvxuGBbZdu8D1y+7jYf+2e//C2KOJm9dxfEqqTHMRXZlR0hRJuKwZau6EJa+MOdjpYN/gprq8xVW7aRp0ZY162ySbktoW'
&& 'vxpPZULGxJLSr+G4UuX+QHrcl/rz/2eqvPgGPPWhqg0KZW5kc3RyZWFtDQplbmRvYmoNCjEwIDAgb2JqDQoyNDYNCmVuZG9iag0K'
&& 'NCAwIG9iag0KPDwNCi9UeXBlIC9QYWdlDQovUGFyZW50IDUgMCBSDQovUmVzb3VyY2VzIDw8DQovRm9udCA8PA0KL0YwIDYgMCBS'
&& 'IA0KL0YxIDcgMCBSIA0KPj4NCi9Qcm9jU2V0IDIgMCBSDQo+Pg0KL0NvbnRlbnRzIDkgMCBSDQo+Pg0KZW5kb2JqDQo2IDAgb2Jq'
&& 'DQo8PA0KL1R5cGUgL0ZvbnQNCi9TdWJ0eXBlIC9UcnVlVHlwZQ0KL05hbWUgL0YwDQovQmFzZUZvbnQgL0FyaWFsDQovRW5jb2Rp'
&& 'bmcgL1dpbkFuc2lFbmNvZGluZw0KPj4NCmVuZG9iag0KNyAwIG9iag0KPDwNCi9UeXBlIC9Gb250DQovU3VidHlwZSAvVHJ1ZVR5'
&& 'cGUNCi9OYW1lIC9GMQ0KL0Jhc2VGb250IC9Cb29rQW50aXF1YSxCb2xkDQovRmlyc3RDaGFyIDMxDQovTGFzdENoYXIgMjU1DQov'
&& 'V2lkdGhzIFsgNzUwIDI1MCAyNzggNDAyIDYwNiA1MDAgODg5IDgzMyAyMjcgMzMzIDMzMyA0NDQgNjA2IDI1MCAzMzMgMjUwIA0K'
&& 'Mjk2IDUwMCA1MDAgNTAwIDUwMCA1MDAgNTAwIDUwMCA1MDAgNTAwIDUwMCAyNTAgMjUwIDYwNiA2MDYgNjA2IA0KNDQ0IDc0NyA3'
&& 'NzggNjY3IDcyMiA4MzMgNjExIDU1NiA4MzMgODMzIDM4OSAzODkgNzc4IDYxMSAxMDAwIDgzMyANCjgzMyA2MTEgODMzIDcyMiA2'
&& 'MTEgNjY3IDc3OCA3NzggMTAwMCA2NjcgNjY3IDY2NyAzMzMgNjA2IDMzMyA2MDYgDQo1MDAgMzMzIDUwMCA2MTEgNDQ0IDYxMSA1'
&& 'MDAgMzg5IDU1NiA2MTEgMzMzIDMzMyA2MTEgMzMzIDg4OSA2MTEgDQo1NTYgNjExIDYxMSAzODkgNDQ0IDMzMyA2MTEgNTU2IDgz'
&& 'MyA1MDAgNTU2IDUwMCAzMTAgNjA2IDMxMCA2MDYgDQo3NTAgNTAwIDc1MCAzMzMgNTAwIDUwMCAxMDAwIDUwMCA1MDAgMzMzIDEw'
&& 'MDAgNjExIDM4OSAxMDAwIDc1MCA3NTAgDQo3NTAgNzUwIDI3OCAyNzggNTAwIDUwMCA2MDYgNTAwIDEwMDAgMzMzIDk5OCA0NDQg'
&& 'Mzg5IDgzMyA3NTAgNzUwIA0KNjY3IDI1MCAyNzggNTAwIDUwMCA2MDYgNTAwIDYwNiA1MDAgMzMzIDc0NyA0MzggNTAwIDYwNiAz'
&& 'MzMgNzQ3IA0KNTAwIDQwMCA1NDkgMzYxIDM2MSAzMzMgNTc2IDY0MSAyNTAgMzMzIDM2MSA0ODggNTAwIDg4OSA4OTAgODg5IA0K'
&& 'NDQ0IDc3OCA3NzggNzc4IDc3OCA3NzggNzc4IDEwMDAgNzIyIDYxMSA2MTEgNjExIDYxMSAzODkgMzg5IDM4OSANCjM4OSA4MzMg'
&& 'ODMzIDgzMyA4MzMgODMzIDgzMyA4MzMgNjA2IDgzMyA3NzggNzc4IDc3OCA3NzggNjY3IDYxMSANCjYxMSA1MDAgNTAwIDUwMCA1'
&& 'MDAgNTAwIDUwMCA3NzggNDQ0IDUwMCA1MDAgNTAwIDUwMCAzMzMgMzMzIDMzMyANCjMzMyA1NTYgNjExIDU1NiA1NTYgNTU2IDU1'
&& 'NiA1NTYgNTQ5IDU1NiA2MTEgNjExIDYxMSA2MTEgNTU2IDYxMSANCjU1NiBdDQovRW5jb2RpbmcgL1dpbkFuc2lFbmNvZGluZw0K'
&& 'L0ZvbnREZXNjcmlwdG9yIDggMCBSDQo+Pg0KZW5kb2JqDQo4IDAgb2JqDQo8PA0KL1R5cGUgL0ZvbnREZXNjcmlwdG9yDQovRm9u'
&& 'dE5hbWUgL0Jvb2tBbnRpcXVhLEJvbGQNCi9GbGFncyAxNjQxOA0KL0ZvbnRCQm94IFsgLTI1MCAtMjYwIDEyMzYgOTMwIF0NCi9N'
&& 'aXNzaW5nV2lkdGggNzUwDQovU3RlbVYgMTQ2DQovU3RlbUggMTQ2DQovSXRhbGljQW5nbGUgMA0KL0NhcEhlaWdodCA5MzANCi9Y'
&& 'SGVpZ2h0IDY1MQ0KL0FzY2VudCA5MzANCi9EZXNjZW50IDI2MA0KL0xlYWRpbmcgMjEwDQovTWF4V2lkdGggMTAzMA0KL0F2Z1dp'
&& 'ZHRoIDQ2MA0KPj4NCmVuZG9iag0KMiAwIG9iag0KWyAvUERGIC9UZXh0ICBdDQplbmRvYmoNCjUgMCBvYmoNCjw8DQovS2lkcyBb'
&& 'NCAwIFIgXQ0KL0NvdW50IDENCi9UeXBlIC9QYWdlcw0KL01lZGlhQm94IFsgMCAwIDYxMiA3OTIgXQ0KPj4NCmVuZG9iag0KMSAw'
&& 'IG9iag0KPDwNCi9DcmVhdG9yICgxNzI1LmZtKQ0KL0NyZWF0aW9uRGF0ZSAoMS1KYW4tMyAxODoxNVBNKQ0KL1RpdGxlICgxNzI1'
&& 'LlBERikNCi9BdXRob3IgKFVua25vd24pDQovUHJvZHVjZXIgKEFjcm9iYXQgUERGV3JpdGVyIDMuMDIgZm9yIFdpbmRvd3MpDQov'
&& 'S2V5d29yZHMgKCkNCi9TdWJqZWN0ICgpDQo+Pg0KZW5kb2JqDQozIDAgb2JqDQo8PA0KL1BhZ2VzIDUgMCBSDQovVHlwZSAvQ2F0'
&& 'YWxvZw0KL0RlZmF1bHRHcmF5IDExIDAgUg0KL0RlZmF1bHRSR0IgIDEyIDAgUg0KPj4NCmVuZG9iag0KMTEgMCBvYmoNClsvQ2Fs'
&& 'R3JheQ0KPDwNCi9XaGl0ZVBvaW50IFswLjk1MDUgMSAxLjA4OTEgXQ0KL0dhbW1hIDAuMjQ2OCANCj4+DQpdDQplbmRvYmoNCjEy'
&& 'IDAgb2JqDQpbL0NhbFJHQg0KPDwNCi9XaGl0ZVBvaW50IFswLjk1MDUgMSAxLjA4OTEgXQ0KL0dhbW1hIFswLjI0NjggMC4yNDY4'
&& 'IDAuMjQ2OCBdDQovTWF0cml4IFswLjQzNjEgMC4yMjI1IDAuMDEzOSAwLjM4NTEgMC43MTY5IDAuMDk3MSAwLjE0MzEgMC4wNjA2'
&& 'IDAuNzE0MSBdDQo+Pg0KXQ0KZW5kb2JqDQp4cmVmDQowIDEzDQowMDAwMDAwMDAwIDY1NTM1IGYNCjAwMDAwMDIxNzIgMDAwMDAg'
&& 'bg0KMDAwMDAwMjA0NiAwMDAwMCBuDQowMDAwMDAyMzYzIDAwMDAwIG4NCjAwMDAwMDAzNzUgMDAwMDAgbg0KMDAwMDAwMjA4MCAw'
&& 'MDAwMCBuDQowMDAwMDAwNTE4IDAwMDAwIG4NCjAwMDAwMDA2MzMgMDAwMDAgbg0KMDAwMDAwMTc2MCAwMDAwMCBuDQowMDAwMDAw'
&& 'MDIxIDAwMDAwIG4NCjAwMDAwMDAzNTIgMDAwMDAgbg0KMDAwMDAwMjQ2MCAwMDAwMCBuDQowMDAwMDAyNTQ4IDAwMDAwIG4NCnRy'
&& 'YWlsZXINCjw8DQovU2l6ZSAxMw0KL1Jvb3QgMyAwIFINCi9JbmZvIDEgMCBSDQovSUQgWzw0NzE0OTUxMDQzM2RkNDg4MmYwNWY4'
&& 'YzEyNDIyMzczND48NDcxNDk1MTA0MzNkZDQ4ODJmMDVmOGMxMjQyMjM3MzQ+XQ0KPj4NCnN0YXJ0eHJlZg0KMjcyNg0KJSVFT0YN'
&& 'CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
&& 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
&& 'AAAAAAAAAAAAAAAAAAAA'.
CALL TRANSFORMATION ID SOURCE x = base64_string RESULT x = result.
ENDMETHOD.
Question also discussed there.

Related

Can someone point me in the right direction to begin parsing this string in dart?

I have a series of string like this:
(((S|69|L || S|69|R || S|72|L || S|72|R) && ((S|62|L && (S|78|L || S|55|L) && (S|77|L || S|1|L)) || (S|62|R && (S|78|R || S|55|R) && (S|77|R || S|1|R)))) && (M|34|L || M|34|R) && (((M|40|L && M|39|L && M|36|L) || (M|40|R && M|39|R && M|36|R)) || ((M|38|L && M|36|L && M|37|L) || (M|38|R && M|36|R && M|37|R))))
And I need to run items that look like S|69|L to see if they satisfy this criteria. You can see that it's a series of && or || operations organized by parentheses.
I'm trying to use this tutorial: https://github.com/petitparser/dart-petitparser
But I'm having trouble getting off of the ground. Can anyone give me an example to get started with this? Maybe I just need more coffee...
Update: Making progress. This at least pulls off outside parentheses. I think I just need to continue to play with it, but I would still appreciate any tips for those who know how this works.
String testString = '((1||2) || 3)';
final inner = undefined();
final paren = (char('(').trim() & inner.star().flatten() & char(')').trim())
.map((values) => values[1]);
inner.set(paren | pattern('^)'));
final parser = inner.end();
final result = parser.parse(testString);
print(result.value);
The grammar you provide in the question seems to work for me and the provided example inputs pass.
A couple of tips:
If you are not interested in the parser output, instead of calling parser.parse(input) you could use parser.accept(input) to get a boolean.
Similarly, if you are not interested in the output, you can drop the calls to flatten() and map(...). Both are used to build an AST. Furthermore, flatten() hides the generated tree, which can make it hard to see what is happening.
For the actual values you could use a primitive parser like the following. However, not sure what your exact specification is?
final primitive = (uppercase() & char('|') & digit().plus() & char('|') & uppercase()).flatten().trim();
If you have the primitive parser, you can add an undefined parser for the logical expression (called outer) like so:
final outer = undefined();
final inner = undefined();
final operator = string('&&') | string('||');
outer.set(inner.separatedBy(operator));
final paren = char('(').trim() & outer & char(')').trim();
inner.set(paren | primitive);
final parser = outer.end();
Building expression parsers can get complicated and unwieldy quite quickly. With the Expression Builder this becomes much simpler:
final builder = ExpressionBuilder();
builder.group().primitive(primitive);
builder.group()
.wrapper(char('(').trim(), char(')').trim(), (l, v, r) => [l, v, r]);
builder.group()
..left(string('&&').trim(), (a, op, b) => [a, '&&', b])
..left(string('||').trim(), (a, op, b) => [a, '||', b]);
final parser = builder.build().end();

Is it possible to limit to size of a List in Reads

My controller receives a json. One of the elements in the json is an array of strings. I have written the following validation for the json
implicit val pQ:Reads[PQ] = (
(JsPath \ "id").readNullable[UUID] and
(JsPath \ "description").read[String] and
(JsPath \ "h").read[List[String]] and
(JsPath \ "i").read[List[String]] and
(JsPath \ "s").read[String] and
(JsPath \ "t").read[Set[String]] and
)(PQ.apply _)
Is it possible to write a Reads or Validate such that the json gets rejected if the size of a List is more than a specified value (say the size of i list should not be more than 3?
I might write another answer where the code is more functional and organised. Happy to accept other answers as well.
The way to customize validating json is to extend Reads trait and implement its reads method.
abstract def reads(json: JsValue): JsResult[A]
I want to achieve two things
1) validate the the json has all the required fields
2) ensure that some of the fields have max-size limit (eg. no. of images which could be sent).
Json validation works by calling validate or validateOpt method of JsValue. These methods expect an implicit Reads and pass the JsValue to it.
def validate[T](implicit rds: Reads[T]): JsResult[T] = rds.reads(this)
So to validate json and map it to my PQ class, I had to create a Reads[PQ]. But because I want validation beyond just the structure of the json, I have to extends Reads and implement my own reads.
To do step 1, I created Reads[PQ] the normal way (just checking that all the required fields are present and can map to my PQ class
implicit val pQStructurallyCorrect:Reads[PQ] = (
(JsPath \ "id").readNullable[UUID] and
(JsPath \ "description").read[String] and
(JsPath \ "h").read[List[String]] and
(JsPath \ "i").read[List[String]] and
(JsPath \ "s").read[String] and
(JsPath \ "t").read[Set[String]] and
)(PQ.apply _)
To add step 2, I created another Reads[PQ] by extending Read[PQ] and by overriding the reads
implicit object PQReads extends Reads[PQ] {
def reads(json:JsValue):JsResult[PQ] = {
//check that the structure of the json is correct by utilizing the Reads created for step 1
val structurallyValidated = json.validateOpt[PQ](pQStructurallyCorrect)
structurallyValidated match {
case JsSuccess(pQOpt,path)=>{ //structure is correct. now check content
val result = pQOpt.map(pq=>{
if(pq.image.length <0 || pq.image.length > 3)
{
JsError("invalid no. of images")
}
else {
JsSuccess(pq)
}
}).getOrElse(JsError("Error in validating Json"))
result
}
case JsError(errors) =>{
JsError(errors)
}
}
}
}
Now to validate the json, I use PQReads object
implicit val qReads:Reads[Q] = (JsPath \ "p-q").read[PQ](PQReads)
.map((x:PQ)=>Q.apply (x))
What is happening above is when my application receives the json,
1) It first gets the body as json from the incoming request
val jsonBodyOption = body.asJson
2) Then the json is validated
val qOption = jsonBody.validateOpt[Q] //this uses qReads:Reads available implicitly
qReads uses PQReads to validate the json. PQReads first calls validateOpt passing pQStructurallyCorrect which checks the structure. If the structure is correct, then the length of image List is checked.

Logical AND operations in Swift not working

I am new to swift and trying to solve a very basic Logical AND problem
if (textField == self.cvv && cvv.text.length == 4 && !string.isEmpty)
{
return false;
}
this is my code
According to this
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html
the && does exists however I am getting error
Couldn't find an overload for the &&
What and how can I use logical operations?
It is not a logical && error: compiler confused by an earlier error:
'String' does not have a member named 'length'
count(cvv.text) is not available either:
See #RMenke's answer for Swift 2.0 syntax.
I just tried this:
var textField = UITextField()
var cvv = UITextField()
var string = ""
if (textField == cvv && cvv.text!.characters.count == 4 && string.isEmpty)
{
return false;
}
I couldn't replicate the error, because I have no idea about the types and declarations of all instances involved. However I got an error on the text.length might be a Swift 1.2 => swift 2.0 change. I updated it to text.characters.count
To more fully answer your question...
&& always worked fine for me, exactly the way you use it.
conditon1 operatorA condition2 && condition3 operatorB conditon4 ...
However the "couldn't find an overload" error is often the result of a type mismatch. Checking an Int against a String for example.

Inverse if statement

I have a question about Objective C
I want an inverted if statement. Like: if (!example.hidden == YES) {
Here's my code:
if ((randomBallTouch.x>_randomColorBall.center.x-(_randomColorBall.frame.size.width)/2) &&
(randomBallTouch.x<_randomColorBall.center.x+(_randomColorBall.frame.size.width)/2) &&
(randomBallTouch.y>_randomColorBall.center.y-(_randomColorBall.frame.size.height)/2) &&
(randomBallTouch.y<_randomColorBall.center.y+(_randomColorBall.frame.size.height)/2)) {
_randomColorBall.center = CGPointMake(randomBallTouch.x, randomBallTouch.y);
if (_randomColorBall.hidden == NO) {
_redBall.center = CGPointMake(_redBall.center.x, _redBall.center.y - 200);
}
}
But when i do: if(!(randomBallTouch.x>_randomColorBall.center.x)) etc. It does not work.
And I can't do else because that will bug with the other two if statements.
Any help?? I am using Xcode 5.1.
You can't just add an ! at the beginning to invert the condition. You need to wrap the whole expression in a set of parentheses first.
If you have:
if (a && b) {
then the inversion is:
if (!(a && b)) {
You didn't add those parentheses.
Try this, just replace your if with this one.
if(!((randomBallTouch.x > (_randomColorBall.center.x-(_randomColorBall.frame.size.width)/2)) && (randomBallTouch.x < (_randomColorBall.center.x+(_randomColorBall.frame.size.width)/2)) && (randomBallTouch.y > (_randomColorBall.center.y-(_randomColorBall.frame.size.height)/2)) &&(randomBallTouch.y < (_randomColorBall.center.y+(_randomColorBall.frame.size.height)/2)))) {
You are missing a lot of parenthesis to make your statement a valid boolean.

Stringify macro values in Objective C?

I'm developing in XCode 4.2, and was wondering how I could stringify macro parameters? I was trying to use # as I thought I would do in C, but to no avail. Here is my macro:
#define ASSIGN_PROPERTY(PROP_NAME, PROP_NAME_PARAM) { \
if (PROP_NAME_PARAM == nil) { \
NSAssert(PROP_NAME != nil, #"#PROP_NAME is already nil"); \
PROP_NAME = nil; \
} else { \
NSAssert1(PROP_NAME == nil, #"#PROP_NAME is already set, address=%p", PROP_NAME); \
PROP_NAME = PROP_NAME_PARAM; \
} \
}
Then in a class that has foo as a property, I define its setter like so:
- (void) setFoo:(NSObject *)fooParam {
ASSIGN_PROPERTY(foo, fooParam)
}
Say a client calls setFoo with a non-nil value, but the foo property is already non-nil. I want the macro to print:
foo is already set, address=0x5e55400
But instead it's printing:
#PROP_NAME is already set, address=0x5e55400
Any advice?
Have you tried something like
NSAssert(PROP_NAME != nil, #"%s is already nil", #PROP_NAME);

Resources