How to write inresponse in indesign scripts - adobe-indesign

I am running this script for getting all form fields of a indd file.
var _ALL_FIELDS = "";
var allFields = myDocument.formFields;
for(var i=0;i<allFields.length;i++){
var tf = allFields[i];
alert(tf.id);
alert(tf.label);
alert(tf.name);
alert(_ALL_FIELDS = _ALL_FIELDS +\",\"+ tf.name);
}
What i have done is, created a soap-java based client and calling the runscript method.
Now i am able to get these fields but how to send these fields back to the client i.e. how to write this in response and then at client side how to read it from response.
Code for calling runscript method is:-
Service inDesignService = new ServiceLocator();
ServicePortType inDesignServer = inDesignService.getService(new URL(parsedArgs.getHost()));
IntHolder errorNumber = new IntHolder(0);
StringHolder errorString = new StringHolder();
DataHolder results = new DataHolder();
inDesignServer.runScript(runScriptParams, errorNumber, errorString, results);
Also I have found in docs that runScript method returns RunScriptResponse but in my case it's returning void.
http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/indesign/sdk/cs6/server/ids-solutions.pdf

It looks like you want to return an array of formField names. You could take advantage of the everyItem() collection interface method in your javascript:
var result = myDocument.formFields.everyItem().name;
result;
The javascript will return the last value in the called script, so just to make it completely obvious, the last line is just the value to be returned.
On the Java side, the runScript method is passing the results variable as the 4th parameter, and that's where you'll find your response. So, after your code snippet, you might have something like this:
List<String> formFieldNames = new ArrayList<String>();
if (results.value.getData() != null) {
Data[] resultsArray = (Data[]) results.value.getData();
for (int i = 0; i < resultsArray.length; i++) {
formFieldNames.add(resultsArray[i].getData().toString());
}
}

Related

Castle Core Invocation create a cache key from intercepted method

I'm using a interface interceptor to cache all methods that starts with "Get" but i can't figure out how to generate a unique cache key for every unknown parameter it can be anything and using GetHashCode is not an option as i can't be 100% sure that they have overridden the GetHashCode.
some thoughts was someting in the line of How can I create a unique hashcode for a JObject?
where JSON is used for a JObject i was thinking on JSON serialize every parameter then get the hash code like explained in the link above:
var obj = JToken.Parse(jsonString);
var comparer = new JTokenEqualityComparer();
var hashCode = comparer.GetHashCode(obj);
However i think this will be a performence hit so how can this be solved ?
The code i have so far is this but it wont handle the complex type situation where .ToString won't generate the raw value type like int, string etc.
private string CreateCacheKey(IInvocation invocation)
{
string className = invocation.TargetType.FullName;
string methodName = invocation.Method.Name;
var builder = new StringBuilder(100);
builder.Append(className);
builder.Append(".");
builder.Append(methodName);
for (int i = 0; i < invocation.Arguments.Length; i++)
{
var argument = invocation.Arguments[i];
var argumentValue = invocation.GetArgumentValue(i);
builder.Append("_");
builder.Append(argument);
if (argument != argumentValue)
{
builder.Append(argumentValue);
}
}
return string.Format("{0}-{1}", this.provider.CacheKey, builder);
}
I ended up using GetHashCode as it is the only viable solution if thay dont override the method it will not cache.

The best way to modify a WebAPI OData QueryOptions.Filter

I am using the OData sample project at http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/working-with-entity-relations. In the Get I want to be able to change the Filter in the QueryOptions of the EntitySetController:
public class ProductsController : EntitySetController<Product, int>
{
ProductsContext _context = new ProductsContext();
[Queryable(AllowedQueryOptions=AllowedQueryOptions.All)]
public override IQueryable<Product> Get()
{
var products = QueryOptions.ApplyTo(_context.Products).Cast<Product>();
return products.AsQueryable();
}
I would like to be able to find properties that are specifically referred to. I can do this by parsing this.QueryOptions.Filter.RawValue for the property names but I cannot update the RawValue as it is read only. I can however create another instance of FilterQueryOption from the modified RawValue but I cannot assign it to this.QueryOptions.Filter as this is read only too.
I guess I could call the new filter's ApplyTo passing it _context.Products, but then I will need to separately call the ApplyTo of the other properties of QueryOptions like Skip and OrderBy. Is there a better solution than this?
Update
I tried the following:
public override IQueryable<Product> Get()
{
IQueryable<Product> encryptedProducts = _context.Products;
var filter = QueryOptions.Filter;
if (filter != null && filter.RawValue.Contains("Name"))
{
var settings = new ODataQuerySettings();
var originalFilter = filter.RawValue;
var newFilter = ParseAndEncyptValue(originalFilter);
filter = new FilterQueryOption(newFilter, QueryOptions.Context);
encryptedProducts = filter.ApplyTo(encryptedProducts, settings).Cast<Product>();
if (QueryOptions.OrderBy != null)
{
QueryOptions.OrderBy.ApplyTo<Product>(encryptedProducts);
}
}
else
{
encryptedProducts = QueryOptions.ApplyTo(encryptedProducts).Cast<Product>();
}
var unencryptedProducts = encryptedProducts.Decrypt().ToList();
return unencryptedProducts.AsQueryable();
}
and it seems to be working up to a point. If I set a breakpoint I can see my products in the unencryptedProducts list, but when the method returns I don't get any items. I tried putting the [Queryable(AllowedQueryOptions=AllowedQueryOptions.All)] back on again but it had no effect. Any ideas why I am not getting an items?
Update 2
I discovered that my query was being applied twice even though I am not using the Queryable attribute. This meant that even though I had items to return the List was being queried with the unencrypted value and therefore no values were being returned.
I tried using an ODataController instead:
public class ODriversController : ODataController
{
//[Authorize()]
//[Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
public IQueryable<Products> Get(ODataQueryOptions options)
{
and this worked! Does this indicate that there is a bug in EntitySetController?
You would probably need to regenerate ODataQueryOptions to solve your issue. Let's say if you want to modify to add $orderby, you can do this like:
string url = HttpContext.Current.Request.Url.AbsoluteUri;
url += "&$orderby=name";
var request = new HttpRequestMessage(HttpMethod.Get, url);
ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Product>("Product");
var options = new ODataQueryOptions<Product>(new ODataQueryContext(modelBuilder.GetEdmModel(), typeof(Product)), request);

LINQ ForEach with Replace

I am trying to replace a string date value "01/01/1700" with an empty string in LINQ.
The date is of type string.
Something like this but I cant get it to work.
Query<Client>(sql).ToList().ForEach(x => x.DateOfBirth =
x.DateOfBirth.Replace("01/01/1700", ""));
This code works but its not LINQ.
var result = Query<Client>(sql).ToList();
foreach (var client in result)
{
if (client.DateOfBirth == "01/01/1700")
{
client.DateOfBirth = "n/a";
}
}
Thanks for your help.
The problem is the ToList(). The result is not visible in the variable you use afterwards.
Try out the following:
var list = Query<Client>(sql).ToList();
list.ForEach(l => l.DateOfBirth = l.DateOfBirth.Replace("01/01/1700", "n/a"));
Should work fine. Use the list variable afterwards.
var result = Query<Client>(sql).ToList();
result.ForEach(l => l.DateOfBirth = l.DateOfBirth.Replace("01/01/1700", "n/a"));
Your code assumes that changes made to an object in a List will be reflected in the Query<Client> that the object came from. Apparently this is not the case. One thing you could try is assigning the list before calling ForEach() and using the list from that point on:
var clients = Query<Client>(sql).ToList();
clients.ForEach(x => x.DateOfBirth = x.DateOfBirth.Replace("01/01/1700", ""));
Also, ForEach is not a LINQ operator. It is a method in the List class. Unlike LINQ operators, it will modify the list that called it and will not return anything. The way to "modify" data with LINQ is by using select:
var clients = (from client in Query<Client>(sql).ToList()
select new Client(client)
{
DateOfBirth = client.DateOfBirth.Replace("01/01/1700", "")
}).ToList();

Refresh MVC View

I have a little app that initially requests a user id. This user id is then sent as a parameter to a stored procedure that returns values from a database. What I would like for this app to do is to refresh those same values every 30 seconds. My issue is that when I refresh, I lose the user id. Is there something simple that I'm missing here?
public ActionResult Report()
{
string operatorCode = Request.Form.GetValues("txtOperator")[0].ToString();
ViewBag.operatorName = (from e in db.employees
where e.operator_code == operatorCode
select e.name).Max().ToString();
ViewData["operatorCode"] = operatorCode;
var results = db.lex_sp_Select_Paintline_FinRew_Operator(operatorCode);
Response.AddHeader("Refresh", "10");
return View(results.ToList());
}
I think the main reason for the null value is due to the fact that you are trying to refresh an HttpPost, rather than a request (the refresh header is not intended for POSTS). I'd suggest as an alternative, that you change your process to be a request, which would result in only needing to change the invoking code (to a get) and changing the Report action to:
string operatorCode = Request.QueryString["txtOperator"];
this should give you the desired result, tho at the expense of the action now being a get rather than a post. You could also store the operatorCode in Session (tho this may not scale very well). The final option that I can see, would be to run an ajax request on a setInterval() and use that process to send a POST to the controller action.
How about storing in temp session and then using it from there when you lost it?
string operatorCode = Request.Form.GetValues("txtOperator")[0].ToString();
TempData["operatorCode"] = operatorCode;
if (!String.IsNullOrEmpty(operatorCode))
{
TempData["operatorCode"] = operatorCode;
ViewBag.operatorName = (from e in db.employees
where e.operator_code == operatorCode
select e.name).Max().ToString();
ViewData["operatorCode"] = operatorCode;
var results = db.lex_sp_Select_Paintline_FinRew_Operator(operatorCode);
Response.AddHeader("Refresh", "10");
return View(results.ToList());
}
else
{
var tempCode = TempData["operatorCode"]
ViewData["operatorCode"] = tempCode;
var results = db.lex_sp_Select_Paintline_FinRew_Operator(tempCode);
Response.AddHeader("Refresh", "10");
return View(results.ToList());
}

django multiple model in dictionary json

I want to pass to create a json output with a dictionary with multiple models, like this:
results = {}
results["game_info_db"] = db.gameInfo.objects.get(name='name')
results["dlc_list_db"] = db.gameAddon.objects.filter(game__name='name')
What i tried is serialize (serializers.serialize) all dicts entrys and after this i dumps (simplejson.dumps) all the dict... but it doesn't seems to be correct ...
any sugestion ?
You could pass in the values of the models and convert it to a list:
results = {}
results["game_info_db"] = list(db.gameInfo.objects.get(name='name').values())
results["dlc_list_db"] = list(db.gameAddon.objects.filter(game__name='name').values())
return HttpResponse(json.dumps(results), mimetype='application/javascript')
The data will appear as objects on the javascript side. Assuming you have a name column, you can access the attributes like the following:
$.getJSON("/ajax/", function(data) {
var dlcs = data.dlc_list_db;
for (i = 0; i < dlcs.length; i++) {
var dlc = dlcs[i];
alert(dlc.name);
}
});

Resources