I have to created a dynamic URLcontaining the user id and email parameters, which will direct to sign up form in my GWT application. I want to set and get the parameters in the query string. I have referred tp http://code.google.com/p/gwt-examples/source/browse/trunk/System/src/com/gawkat/gwt/system/client/global/QueryString.java?r=1241 but here QueryStringData is inaccessible to my project.Please tell me how I can do it? Any alternative could also help me.
#Stein, but there is (a query parameter tokenizer in GWT): e.g. Window.Location.getParameter("debug") will return the string value of the parameter debug.
Don't think there's a simple tokenized query string parser in GWT. But you can get the raw query string by using:
String queryString = Window.Location.getQueryString();
Parse it any way you like. I use it like this to set debug flags etc.:
boolean debugMode = Window.Location.getQueryString().indexOf("debug=true") >= 0;
Note that changing values in the query part of the url (between the ? and the #) will reload the page. While changing the "hash part" of the url (anything after the #) will not reload the page. Which is why the com.google.gwt.user.client.History uses the hash part.
If you want really want to parse the history token (hash part) to encode parameters, here's the code for that:
private static Map<String, String> buildHashParameterMap() {
final String historyToken = History.getToken();
Map<String, String> paramMap = new HashMap<String, String>();
if (historyToken != null && historyToken.length() > 1) {
for (String kvPair : historyToken.split("&")) {
String[] kv = kvPair.split("=", 2);
if (kv.length > 1) {
paramMap.put(kv[0], URL.decodeQueryString(kv[1]));
} else {
paramMap.put(kv[0], "");
}
}
}
return paramMap;
}
There is in-built support for getting all of the parameters.
Simply call:
Map<String, List<String>> parameterMap = Window.Location.getParameterMap();
Related
I am doing pagination in REST api developed over slim.
Using below API to get current uri
(string) $request->getUri();
RESULT ::http://localhost/slim/test_app/test/public/api/actions/?page=2
But now for next request i need to replace the page number in current url to (+1) ie 3 here and pass in data returned to user like below
{
"data":[
//data
]
"next": http://localhost/slim/test_app/test/public/api/actions/?page=3
}
What could be the best way to replace the page number ? Do we have any direct api for this,to just replace the attributes ?
I added a function to merge attributes and than bind the query to url as below function
private function merge_querystring($url = null,$query = null,$recursive = false)
{
if($url == null)
return false;
if($query == null)
return $url;
// split the url into it's components
$url_components = parse_url($url);
// if we have the query string but no query on the original url
// just return the URL + query string
if(empty($url_components['query']))
return $url.'?'.ltrim($query,'?');
// turn the url's query string into an array
parse_str($url_components['query'],$original_query_string);
// turn the query string into an array
parse_str(parse_url($query,PHP_URL_QUERY),$merged_query_string);
// merge the query string
if($recursive == true)
$merged_result = array_merge_recursive($original_query_string,$merged_query_string);
else
$merged_result = array_merge($original_query_string,$merged_query_string);
// Find the original query string in the URL and replace it with the new one
return str_replace($url_components['query'],http_build_query($merged_result),$url);
}
and i use below to add query to url
$postQuery["page"]=$currentpage+1;
//print_r($postQuery);
//echo http_build_query($postQuery);
$data["next"]= $this->merge_querystring($request->getUri(),"?".http_build_query($postQuery));
You can replace pagination value by string manipulation. But you can also using what Slim provide.
Slim\Http\Uri class, which implements Psr\Http\Message\UriInterface, has withQuery() method that will replace current query string.
It will return cloned Slim\Http\Uri instance with its query string replaced.
$query = $request->getQueryParams();
$query['page'] = $query['page'] + 1;
$url = $request->getUri();
$nextUrl = $url->withQuery(http_build_query($query));
$data['next'] = (string) $nexUrl;
I have a RequestMaping that get a Search json class as body params.
I want to create proper Specification from this search json object so that pass to my Repository like this:
pagesResult = myRepository.findAll(mySpec)
I have problme with parsing and Dynamically add items to specification. I want to achieve something like this:
#Override
public Phones searchPhones(int pageNumber, Map<String, String> searchObject) {
List<PhoneSpecification> specificationslist = new ArrayList<>();
generateSpecifications(searchObject, specificationslist); //fill specificationList
Specification<Phone> specificationOfPhone;
for (PhoneSpecification spec :
specificationslist) {
//this is my problem , I had to dynamically increase my Specification like this:
specificationOfPhone = specificationOfPhone + Specifications.and(spec);
}
mobileRepository.findAll(specificationOfPhone);
I finally achieve this by adding where to first specification and handle all by adding like this:
if(specificationslist.size()>0){
finalSpecification = Specifications.where(specificationslist.get(0)) ;
}
for (int i=1 ; i<specificationslist.size(); i++) {
finalSpecification = Specifications.where(finalSpecification).and(specificationslist.get(i));
}
You can change your code to this:
Specifications<Phone> specificationOfPhone = Specifications.where(null);
for (PhoneSpecification spec : specificationslist) {
specificationOfPhone = specificationOfPhone.and(spec);
}
I assumed that PhoneSpecification is extending/implements Specification<T>.
Specifications.where(null); will return empty specification which can be chained with others.
Because Specifications<T> extends Specification<T> you can use it with your findAll method.
I have some word templates(maybe thousands). Each template has merge fields which will be filled from database. I don`t like writing separate code for every template and then build the application and deploy it whenever a template is changed or a field on the template is added!
Instead, I'm trying to define all merge fields in a separate xml file and for each field I want to write the "query" which will be called when needed. EX:
mergefield1 will call query "Case.Parties.FirstOrDefault.NameEn"
mergefield2 will call query "Case.CaseNumber"
mergefield3 will call query "Case.Documents.FirstOrDefault.DocumentContent.DocumentType"
Etc,
So, for a particular template I scan its merge fields, and for each merge field I take it`s "query definition" and make that request to database using EntityFramework and LINQ. Ex. it works for these queries: "TimeSlots.FirstOrDefault.StartDateTime" or
"Case.CaseNumber"
This will be an engine which will generate word documents and fill it with merge fields from xml. In addition, it will work for any new template or new merge field.
Now, I have worked a version using reflection.
public string GetColumnValueByObjectByName(Expression<Func<TEntity, bool>> filter = null, string objectName = "", string dllName = "", string objectID = "", string propertyName = "")
{
string objectDllName = objectName + ", " + dllName;
Type type = Type.GetType(objectDllName);
Guid oID = new Guid(objectID);
dynamic Entity = context.Set(type).Find(oID); // get Object by Type and ObjectID
string value = ""; //the value which will be filled with data from database
IEnumerable<string> linqMethods = typeof(System.Linq.Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).Select(s => s.Name).ToList(); //get all linq methods and save them as list of strings
if (propertyName.Contains('.'))
{
string[] properies = propertyName.Split('.');
dynamic object1 = Entity;
IEnumerable<dynamic> Child = new List<dynamic>();
for (int i = 0; i < properies.Length; i++)
{
if (i < properies.Length - 1 && linqMethods.Contains(properies[i + 1]))
{
Child = type.GetProperty(properies[i]).GetValue(object1, null);
}
else if (linqMethods.Contains(properies[i]))
{
object1 = Child.Cast<object>().FirstOrDefault(); //for now works only with FirstOrDefault - Later it will be changed to work with ToList or other linq methods
type = object1.GetType();
}
else
{
if (linqMethods.Contains(properies[i]))
{
object1 = type.GetProperty(properies[i + 1]).GetValue(object1, null);
}
else
{
object1 = type.GetProperty(properies[i]).GetValue(object1, null);
}
type = object1.GetType();
}
}
value = object1.ToString(); //.StartDateTime.ToString();
}
return value;
}
I`m not sure if this is the best approach. Does anyone have a better suggestion, or maybe someone has already done something like this?
To shorten it: The idea is to make generic linq queries to database from a string like: "Case.Parties.FirstOrDefault.NameEn".
Your approach is very good. I have no doubt that it already works.
Another approach is using Expression Tree like #Egorikas have suggested.
Disclaimer: I'm the owner of the project Eval-Expression.NET
In short, this library allows you to evaluate almost any C# code at runtime (What you exactly want to do).
I would suggest you use my library instead. To keep the code:
More readable
Easier to support
Add some flexibility
Example
public string GetColumnValueByObjectByName(Expression<Func<TEntity, bool>> filter = null, string objectName = "", string dllName = "", string objectID = "", string propertyName = "")
{
string objectDllName = objectName + ", " + dllName;
Type type = Type.GetType(objectDllName);
Guid oID = new Guid(objectID);
object Entity = context.Set(type).Find(oID); // get Object by Type and ObjectID
var value = Eval.Execute("x." + propertyName, new { x = entity });
return value.ToString();
}
The library also allow you to use dynamic string with IQueryable
Wiki: LINQ-Dynamic
While GWT is not emulate all java's core, what can be used as alternative for:
String.format("The answer is - %d", 42)?
What is the ellegant and efficient pattern to inject arguments to message in GWT?
One elegant solution is using SafeHtml templates. You can define multiple such templates in an interface like:
public interface MyTemplates extends SafeHtmlTemplates {
#Template("The answer is - {0}")
SafeHtml answer(int value);
#Template("...")
...
}
And then use them:
public static final MyTemplates TEMPLATES = GWT.create(MyTemplates.class);
...
Label label = new Label(TEMPLATES.answer(42));
While this is a little bit more work to set up, it has the enormous advantage that arguments are automatically HTML-escaped. For more info, see https://developers.google.com/web-toolkit/doc/latest/DevGuideSecuritySafeHtml
If you want to go one step further, and internationalize your messages, then see also https://developers.google.com/web-toolkit/doc/latest/DevGuideI18nMessages#SafeHtmlMessages
You can simply write your own format function instead of doing brain storm.
public static String format(final String format, final String... args,String delimiter) {
String[] split = format.split(delimiter);//in your case "%d" as delimeter
final StringBuffer buffer= new StringBuffer();
for (int i= 0; i< split.length - 1; i+= 1) {
buffer.append(split[i]);
buffer.append(args[i]);
}
buffer.append(split[split.length - 1]);
return buffer.toString();
}
Because most (as in 99.999%) message formats are static, known at compile-time, the way GWT approaches it is to parse them at compile-time.
You'll generally use a Messages subinterface for its ability to localize the message, but you'll sometimes rather need SafeHtmlTemplates.
In the 0.001% when template is not known at compile time you can use Javascript sprintf (see: http://www.diveintojavascript.com/projects/javascript-sprintf) as in:
public static native String format (String format, JsArrayMixed values) /*-{
return vsprintf(format, values);
}-*/;
You can write your own.
I wrote a version that just work with Strings(%s):
public static String format(final String format, final Object... args)
{
checkNotNull(format);
checkNotNull(args);
final String pattern = "%s";
int start = 0, last = 0, argsIndex = 0;
final StringBuilder result = new StringBuilder();
while ((start = format.indexOf(pattern, last)) != -1)
{
if (args.length <= argsIndex)
{
throw new IllegalArgumentException("There is more replace patterns than arguments!");
}
result.append(format.substring(last, start));
result.append(args[argsIndex++]);
last = start + pattern.length();
}
if (args.length > argsIndex)
{
throw new IllegalArgumentException("There is more arguments than replace patterns!");
}
result.append(format.substring(last));
return result.toString();
}
why not writing a method like:
String appendAnswer(int result) {
return "The answer is - " + Integer.toString(result);
}
is resolving your problem because you do nothing like formatting in your code.
if you ever face the problem like converting integer/byte to Hex String you should use:
Integer.toString(int, 16);
I don't know GWT much but I am working on a GWT project and I needed this. While trying some alternatives, I have found that this is working;
import java.text.MessageFormat;
MessageFormat.format("The answer is - {0}", 42);
I don't know if the project's developers added something special to make this work or it is working by default.
i would like to access some built in properties(like author,last modified date,etc.) of an open xml word doc file. i would like to use open xml sdk2.0 for this purpose. so i wonder if there is any class or any way i could programmatically access these builtin properties.
An explanation of the following method can be found here, but pretty much you need to pass in the properties that you want to get out of the core.xml file to this method and it will return the value:
public static string WDRetrieveCoreProperty(string docName, string propertyName)
{
// Given a document name and a core property, retrieve the value of the property.
// Note that because this code uses the SelectSingleNode method,
// the search is case sensitive. That is, looking for "Author" is not
// the same as looking for "author".
const string corePropertiesSchema = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";
const string dcPropertiesSchema = "http://purl.org/dc/elements/1.1/";
const string dcTermsPropertiesSchema = "http://purl.org/dc/terms/";
string propertyValue = string.Empty;
using (WordprocessingDocument wdPackage = WordprocessingDocument.Open(docName, true))
{
// Get the core properties part (core.xml).
CoreFilePropertiesPart corePropertiesPart = wdPackage.CoreFilePropertiesPart;
// Manage namespaces to perform XML XPath queries.
NameTable nt = new NameTable();
XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
nsManager.AddNamespace("cp", corePropertiesSchema);
nsManager.AddNamespace("dc", dcPropertiesSchema);
nsManager.AddNamespace("dcterms", dcTermsPropertiesSchema);
// Get the properties from the package.
XmlDocument xdoc = new XmlDocument(nt);
// Load the XML in the part into an XmlDocument instance.
xdoc.Load(corePropertiesPart.GetStream());
string searchString = string.Format("//cp:coreProperties/{0}", propertyName);
XmlNode xNode = xdoc.SelectSingleNode(searchString, nsManager);
if (!(xNode == null))
{
propertyValue = xNode.InnerText;
}
}
return propertyValue;
}
You can also use the packaging API:
using System.IO.Packaging.Package;
[...]
using (var package = Package.Open(path))
{
package.PackageProperties.Creator = Environment.UserName;
package.PackageProperties.LastModifiedBy = Environment.UserName;
}
That works also for other open XML formats like power point.
package.Save();
Then
package.closed;
I think that Is the best way.