RESTEasy: getPathSegments().get(1); - resteasy

Can someone tell me what "PathSegment model = info.getPathSegments().get(1);" do, specifically, what does he getPathSegments().get(1) mean? Please provide a sample URL for demonstration. The book didn't give an example URL for this one.
Also, is there such a thing as get(0); ?
#Path("/cars/{make}")
public class CarResource
{
#GET
#Path("/{model}/{year}")
#Produces("image/jpeg")
public Jpeg getPicture(#Context UriInfo info)
{
String make = info.getPathParameters().getFirst("make");
PathSegment model = info.getPathSegments().get(1);
String color = model.getMatrixParameters().getFirst("color");
...
}
}
Thanks again,

If you split the path of a URL by a '/' you'll get a list of path-segments. So e.g. the path /cars/ford/mustang/1976 contains the four segments [cars, ford, mustang, 1976]. info.getPathSegments().get(1) should return the segment ford.
The PathSegment holds also the associated MatrixParameters of the current segment. MatrixParameters can be used if you want to filter the resources with a parameter that affects only one segment like here:
/cars/ford/mustang;generation=two/1976

Related

Need to optimize the code for mapping codes to description

I have a Text field that has semicolon separated codes. These code has to be replaced with the description. I have separate map that have code and description. There is a trigger that replace the code with their description. the data will loaded using the dataloader in this field. I am afraid, it might not work for large amount of data since I had to use inner for loops. Is there any way I can achieve this without inner for loops?
public static void updateStatus(Map<Id,Account> oldMap,Map < Id, Account > newMap)
{
Map<String,String> DataMap = new Map<String,String>();
List<Data_Mapper__mdt> DataMapList = [select Salseforce_Value__c,External_Value__c from Data_Mapper__mdt where
active__c = true AND Field_API_Name__c= :CUSTOMFIELD_MASSTATUS AND
Object_API_Name__c= :OBJECT_ACCOUNT];
for(Data_Mapper__mdt dataMapRec: DataMapList){
DataMap.put(dataMapRec.External_Value__c,dataMapRec.Salseforce_Value__c);
}
for(Account objAcc : newMap.values())
{
if(objAcc.Status__c != ''){
String updatedDescription='';
List<String> delimitedList = objAcc.Status__c.split('; ');
for(String Code: delimitedList) {
updatedDescription = DataMap.get(Code);
}
objAcc.Status__c = updatedDescription;
}
It should be fine. You have a map-based access acting like a dictionary, you have a query outside of the loop. Write an unit test that populates close to 200 accounts (that's how the trigger will be called in every data loader iteration). There could be some concerns if you'd have thousands of values in that Status__c but there's not much that can be done to optimise it.
But I want to ask you 3 things.
The way you wrote it the updatedDescription will always contain the last decoded value. Are you sure you didn't want to write something like updatedDescription += DataMap.get(Code) + ';'; or maybe add them to a List<String> and then call String.join on it. It looks bit weird. If you truly want first or last element - I'd add break; or really just access the last element of the split (and then you're right, you're removing the inner loop). But written like that this looks... weird.
Have you thought about multiple runs. I mean if there's a workflow rule/flow/process builder - you might enter this code again. And because you're overwriting the field I think it'll completely screw you over.
Map<String, String> mapping = new Map<String, String>{
'one' => '1',
'two' => '2',
'three' => '3',
'2' => 'lol'
};
String text = 'one;two';
List<String> temp = new List<String>();
for(String key : text.split(';')){
temp.add(mapping.get(key));
}
text = String.join(temp, ';');
System.debug(text); // "1;2"
// Oh noo, a workflow caused my code to run again.
// Or user edited the account.
temp = new List<String>();
for(String key : text.split(';')){
temp.add(mapping.get(key));
}
text = String.join(temp, ';');
System.debug(text); // "lol", some data was lost
// And again
temp = new List<String>();
for(String key : text.split(';')){
temp.add(mapping.get(key));
}
text = String.join(temp, ';');
System.debug(text); // "", empty
Are you even sure you need this code. Salesforce is perfectly fine with having separate picklist labels (what's visible to the user) and api values (what's saved to database, referenced in Apex, validation rules...). Maybe you don't need this transformation at all. Maybe your company should look into Translation Workbench. Or even ditch this code completely and do some search-replace before invoking data loader, in some real ETL tool (or even MS Excel)

Is there a simpler way to decode this json in Go?

I am trying to parse some JSON from Jira to variables. This is using the go-jira package (https://godoc.org/github.com/andygrunwald/go-jira)
Currently I have some code to get the developer:
dev := jiraIssue.Fields.Unknowns["customfield_11343"].(map[string]interface{})["name"]
and team := jiraIssue.Fields.Unknowns["customfield_12046"].([]interface{})[0].(map[string]interface{})["value"]
to get the team they are a part of from.
Getting the team they are on is a bit gross, is there a cleaner way to get the team besides having to type assert, set the index, then type assert again?
Here is the complete json (modified but structure is same, its way too long):
{
"expand":"renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations",
"id":"136944",
"self":"https://jira.redacted.com/rest/api/2/issue/136944",
"key":"RM-2506",
"fields":{
"customfield_11343":{
"self":"https://redacted.com/rest/api/2/user?username=flast",
"name":"flast",
"key":"flast",
"emailAddress":"flast#redacted.com",
"displayName":"first last",
"active":true,
"timeZone":"Europe/London"
},
"customfield_12046":[
{
"self":"https://jira.redacted.com/rest/api/2/customFieldOption/12045",
"value":"diy",
"id":"12045"
}
],
}
Thanks
The way I go about problems like this is:
Copy some JSON with things I am interested in and paste it into https://mholt.github.io/json-to-go/
Remove fields that arenĀ“t of interest.
Just read the data and unmarshal.
You might end up with something like this given the two custom fields of interest, but you can cut the structure down further if you just need the name.
type AutoGenerated struct {
Fields struct {
Customfield11343 struct {
Self string `json:"self"`
Name string `json:"name"`
Key string `json:"key"`
EmailAddress string `json:"emailAddress"`
DisplayName string `json:"displayName"`
Active bool `json:"active"`
TimeZone string `json:"timeZone"`
} `json:"customfield_11343"`
Customfield12046 []struct {
Self string `json:"self"`
Value string `json:"value"`
ID string `json:"id"`
} `json:"customfield_12046"`
} `json:"fields"`
}
The effect you get is that all extra information in the feed is discarded, but you get the data you want very cleanly.
This is a tough one since the second one is in an array form. It makes it hard to use a map.
For the first one, it's simple enough to use:
type JiraCustomField struct {
Self string `json:"self"`
Name string `json:"name"`
Key string `json:"key"`
EmailAddress string `json:"emailAddress"`
DisplayName string `json:"displayName"`
Active bool `json:"active"`
TimeZone string `json:"timeZone"`
}
type JiraPayload struct {
Expand string `json:"expand"`
ID string `json:"id"`
Key string `json:"key"`
Fields map[string]JiraCustomField `json:"fields"`
}
https://play.golang.org/p/y8-g6r0kInV
Specifically this part Fields map[string]JiraCustomField for the second case it looks like you need it in an array form like Fields map[string][]JiraCustomField.
In a case like this, I think you'll need to make your own Unmarshaler. This is a good tutorial: https://blog.gopheracademy.com/advent-2016/advanced-encoding-decoding/
What you could do with your custom Unmarshal/marshaler, is use the Reflection package and check if it's an array or a struct. If it's a struct then put it into an array, and store it in Fields map[string][]JiraCustomField.

How do I encode an array of Byte32 values for Web3j to pass to my smart contract?

Contract function is defined as:
function createAggregate (string memory key, bytes32[2] memory part_array) public returns (bytes32)
and have incoming a list of parts, defined as...
List<Bytes32> elements
so was trying to use:
List<Type> items = new ArrayList<Type>();
items.add(...); // user reference
items.add(new DynamicArray<>(elements));
final Function function = new Function("createAggregate",
items,
Arrays.asList(new TypeReference<Bytes32>() {})
);
...
But this does not work, seems to be an encoding issue - what is the right what of encoding the Bytes32 ? (This seems to work fine for an array of strings)
Sort of solved this with the following (although was really looking for a more dynamic size solution)
new StaticArray2(Bytes32.class, Utils.typeMap(elements, Bytes32.class));

using a variable name to load movie clip to stage using As3

I have created a Spelling Puzzle in AS3 that loads a list of words from an XML file into an Array.
As the code loops through the array, it assigns each word to a variable called "current_word", then scrambles the letters of "current_word" and displays them on stage.
I would like to add an animated MovieClip as a visual aid with the class name that matches the value of current word.
For example if the current word is 'bear', then a MovieClip with the class name 'bear' is loaded from library to stage.
I was trying to create an empty movie clip called "tempItemClip" and overwrite its value with the value of the var current_word.
No errors, but it's not working. I am new to ActionScript. Can someone advise me on the best solution?
public function getWord()
{
current_word=pWord[ques_num];
setTiles(current_word.length);
ques_num++;
trace(current_word);
var tempItemClip:MovieClip = new MyItem();
Puzzle_screen.addChildAt(tempItemClip,4);
tempItemClip.x=380;
tempItemClip.y=130;
//var myClip:Object = getDefinitionByName(current_word);
var myClip:MovieClip = new MovieClip();
tempItemClip[current_word] = myClip;
tempItemClip.addChild(myClip);
}
It's not clear what you are asking, but I believe this is what you want :
var clipClass:Class = getDefinitionByName(current_word) as Class;
var myClip:MovieClip = new clipClass();

How to Extract Apache Camel URI parameters

Does anyone know how to extract parameter from camel URI?
I have a route defined like this
from("SOME_URI")
.to("SOME_URI")
.to("bean:myBean?method=myMethod&myParameter1=val1&myParameter2=val2")
I want to extract parameter1 and parameter2 in "myMethod" like this (I'm implementing camel in Grails)
def myMethod(def inBody, Exchange exchange){
String parameter1 = extractParameter('myParameter1')
String parameter2 = extractParameter('myParameter2')
...//rest of code
return something
}
Thank's in advance!
Main Answer
You can get what you're looking for out of the exchange:
exchange.getFromEndpoint()
Will return the Endpoint defined by "SOME_URI" and:
exchange.getFromEndpoint().getEndpointUri()
will return the String value of "SOME_URI"
Meaning your code could become:
def myMethod(def inBody, Exchange exchange){
def uri = exchange?.fromEndpoint?.endpointUri
if(uri) {
String parameter1 = extractParameter(uri, 'myParameter1')
String parameter2 = extractParameter(uri, 'myParameter2')
//...rest of code
}
return something
}
/*
* do any kind of processing you want here to manipulate the string
* and return the parameter. This code should work just fine in grails
*/
def extractParameter(String uri, String parameterName) {
def m = uri =~ "${parameterName}=([^&]+)"
return m.find() ? m[0][1] : null
}
If a Java equivalent is preferred, this should do the same:
private static String extractParameter(String uri, String parameterName) {
Matcher m = Pattern.compile(parameterName + "=([^&]+)").matcher(uri);
return m.find() ? m.group(1) : null
}
Alternative
Also note that, depending on what exactly you're trying to accomplish, a better approach might be to use the fromF DSL to supply parameters directly to your route. That way, you have the parameters available in code and you don't have to worry about extracting them, afterward.
The code snippet below is taken from the Camel Documentation of FromF.
fromF("file://%s?include=%s", path, pattern).toF("mock:%s", result);
Are val1 and val2 hardcoded values, or should they be some kind of dynamic value, maybe from the message itself?
The Camel bean component allows you to define the binding, and pass in values from the message or fixed values. See more details at: http://camel.apache.org/bean-binding.html
And you would also need to look at the number of parameters in your method signature, and the number of parameters you define in the Camel bean binding uri. They should match up.
If I understand correctly, you are trying to pass parameters into a method that is going to be invoked. The usual way to do this is to modify the Exchange object as it's flowing through the route.
from("SOME_URI")
.to("SOME_URI")
.setHeader("myParameter1", constant("val1"))
.setHeader("myParameter2", constant("val2"))
.to("bean:myBean?method=myMethod")
In your method, you just access the headers of the Exchange.
def myMethod(Exchange exchange) {
String parameter1 = exchange.getHeader("myParameter1", String.class)
String parameter2 = exchange.getHeader("myParameter2", String.class)
//...rest of code
}
Or if you want to get fancy and use Camel's bean binding,
def myMethod(Exchange exchange,
#Header("myParameter1") String parameter1,
#Header("myParameter2") String parameter2) {
//...rest of code
}
Please remember to vote up if this helps.

Resources