URL Traversal in Lift Framework - url-routing

When I was using Pyramid Framework, I has discovered great method to route urls, named traversal.
Pyramid Traversal first maps request path to the traversal sequence (for example '/a/b/c' => [u'a', u'b', u'c']), and then traverse it consecutive through resources graph.
I am looking for some library or appoach for doing URL traversal in Lift.

If there is no such library, the basics would not be that hard to implement.
Pseudocode:
//handlers is a hashtable which maps resource class -> handler function
my_catchall_route_handler( url )
{
context = My_root_resource()
for segment in split(url)
try
context = context.get_child( segment ) //try to get child resource
except
break //found ultimate context
handler = handlers(context)
handler();
}

Related

Does CRM context allow for structuring code in a non-nested way?

I'm building a Silverlight Web Resource which is intended to integrate into a form, and it needs to know all of the following information:
id of the current user
id of teams current user belongs to
id of current user's security roles
I'm working in an early-bound kind of way, added a Service Reference to the OData endpoint (http://server/org/XRMservices/2011/OrganizationData.svc) which in turn provides me with the context (let's name it cmtestcontext, which is its actual name in code).
I access data through this class (I didn't create it, I just googled it out of the net some time ago: this is a stripped-down, keep-it-short version)
public class QueryInterface
{
//NOTE: ServiceReference1 is the name of the OData service reference
//Add Service Reference -> point to CRM OData url
public ServiceReference1.cmtextcontext CrmContext;
public QueryInterface()
{
var crmServerUrl = (string)GetContext().Invoke("getServerUrl");
if (crmServerUrl.EndsWith("/")) crmServerUrl = crmServerUrl.Substring(0, crmServerUrl.Length - 1);
Uri ODataUri = new Uri(crmServerUrl + "/xrmservices/2011/organizationdata.svc/", UriKind.Absolute);
CrmContext = new cmtestContext(ODataUri) { IgnoreMissingProperties = true };
}
}
The class allows me to sort of fetch in one line, as follows (actual code snippet enveloped in a dummy method to make it copy-pastable):
void RetrieveAllInformationFromCRM()
{
QueryInterface qi = new QueryInterface();
List<Guid> allData = new List<Guid>();
//NOTE: STEP 1 - USER ID
//NOTE: Since this is a web resource, I can cheat and use Xrm.Page.context.getUserId()
//NOTE: Remove the extra '{}' from the result for it to be parsed!
allData.Add(new Guid(qi.GetContext().Invoke("getUserId").ToString().Substring(1,36)));
//NOTE: STEP 2a - TEAM MEMBERSHIP FOR USER
//NOTE: TeamMembership entity links users to teams in a N:N relationship
qi.crmContext.TeamMembershipSet.BeginExecute(new AsyncCallback((result) =>
{
var teamMemberships = qi.crmContext.TeamMembershipSet.EndExecute(result)
.Where(tm => tm.TeamId.HasValue && (tm.SystemUserId ?? Guid.Empty) == userId)
.Select(tm => tm.TeamId.Value);
//NOTE: STEP 2b - TEAMS RELATED TO TEAMMEMBERSHIPS
qi.crmContext.TeamSet.BeginExecute(new AsyncCallback((result2) =>
{
var teamDetails = qi.crmContext.TeamSet.EndExecute(result2)
.Where(t => teamMemberships.Contains(t.TeamId));
foreach (var team in teamDetails)
allData.Add(team.TeamId);
//NOTE: FINAL STEP - allData is filled and ready to be used.
}), null);
}), null);
}
In the code above, my FINAL STEP picks up allData and processes it, and the flow goes on. My concern is, if/when I'll need to modify this "reader" method I'll have to cut and paste the "final" code around to ensure it's placed after all the reads. I'd like it way better if I could just make the reads follow one another, so I could do this:
void MyReaderMethod()
{
ReadEverything();
ProcessData();
}
Basically, can you just wait for a request to finish ? Hanging UI is a non-issue, I'd just wrap the code in a BackgroundWorker along with a "Please Wait" splash.
The nicest (IMO) is to convert the Async method calls (a requirement of Silverlight) into Task based calls.
With tasks you can easily seperate the query from the result action.
Then using the Async BCL's (via nuget) you can use async/await (if you are not using VS2012, then Tasks are still nicer to work with, you will just have to use continuations)
This example is for late bound, but you can modify it for your needs
public Task<OrganizationResponse> ExecuteAsync(OrganizationRequest request)
{
return Task.Factory.FromAsync<OrganizationResponse>(
(callback, state) => Begin(() => service.BeginExecute(request, callback, state)),
service.EndExecute,
null);
}
Then you can use it like
async void MyReaderMethod()
{
//TODO:wrap in try/catch
var result = await ExecuteAsync( ... );
ProcessData(result);
}
Or for VS 2010
void MyReaderMethod()
{
ExecuteAsync( ... ).ContinueWith(task =>{
//TODO: Error handling
ProcessData(task.Result);
});
}

Storing the Cursor for App Engine Pagination

I'm trying to implement pagination using App Engine's RPC and GWT (it's an app engine connected project).
How can I pass both the query results and the web-safe cursor object to the GWT client from the RPC?
I've seen examples using a servlet but I want to know how to do it without a servelt.
I've considered caching the cursor on the server using memcache but I'm not sure if that's appropriate or what should be used as the key (session identifier I would assume, but I'm not sure how those are handled on App Engine).
Links to example projects would be fantastic, I've been unable to find any.
OK, so the best way to do this is to store the cursor as a string on the client.
To do this you have to create a wrapper class that is transportable so you can pass back it to the client via RequestFactory that can hold the results list and the cursor string. To do that you create a normal POJO and then a proxy for it.
here's what the code looks like for the POJO:
public class OrganizationResultsWrapper {
public List<Organization> list;
public String webSafeCursorString;
public List<Organization> getList() {
return list;
}
public void setList(List<Organization> list) {
this.list = list;
}
public String getWebSafeCursorString() {
return this.webSafeCursorString;
}
public void setWebSafeCursorString(String webSafeCursorString) {
this.webSafeCursorString = webSafeCursorString;
}
}
for the proxy:
#ProxyFor(OrganizationResultsWrapper.class)
public interface OrganizationResultsWrapperProxy extends ValueProxy{
List<OrganizationProxy> getList();
void setList(List<OrganizationProxy> list);
String getWebSafeCursorString();
void setWebSafeCursorString(String webSafeCursorString);
}
set up your service and requestFactory to use the POJO and proxy respectively
// service class method
#ServiceMethod
public OrganizationResultsWrapper getOrganizations(String webSafeCursorString) {
return dao.getOrganizations(webSafeCursorString);
}
// request factory method
Request<OrganizationResultsWrapperProxy> getOrganizations(String webSafeCursorString);
Then make sure and run the RPC wizard so that your validation process runs otherwise you'll get a request context error on the server.
Here's the implementation in my data access class:
public OrganizationResultsWrapper getOrganizations(String webSafeCursorString) {
List<Organization> list = new ArrayList<Organization>();
OrganizationResultsWrapper resultsWrapper = new OrganizationResultsWrapper();
Query<Organization> query = ofy().load().type(Organization.class).limit(50);
if (webSafeCursorString != null) {
query = query.startAt(Cursor.fromWebSafeString(webSafeCursorString));
}
QueryResultIterator<Organization> iterator = query.iterator();
while (iterator.hasNext()) {
list.add(iterator.next());
}
resultsWrapper.setList(list);
resultsWrapper.setWebSafeCursorString(iterator.getCursor().toWebSafeString());
return resultsWrapper;
}
a second option would be to save the webSafeCursorString in the memcache, as you already mentioned.
my idea looks like this:
the client sends always request like this "getMyObjects(Object... myParams, int maxResults, String clientPaginationString)". the clientPaginationString is uniquely created like shown below
server receives request and looks into the memcache if there is a webSafeCursorString for the key clientPaginationString
if the server finds nothing, he creates the query and save the webSafeCursorString into memcache with the clientPaginationString as the key. -> returns the results
if the server finds the webSafeCursorString he restarts the query with it and returns the results
the problems are how to clean the memcache and how to find a unique clientPaginationString:
a unique clientPaginationString should be the current UserId + the params of the current query + timestemp. this should work just fine!
i really can't think of a easy way how to clean the memcache, however i think we do not have to clean it at all.
we could store all the webSafeCursorStrings and timestemps+params+userid in a WebSafeCursor-Class that contains a map and store all this in the memcache... and clean this Class ones in a while (timestamp older then...).
one improvement i can think of is to save the webSafeCursorString in the memcache with a key that is created on the server (userSessionId + servicename + servicemethodname + params). however, important is that the client sends an information if he is interested in a new query (memcache is overriden) or wants the next pagination results (gets webSafeCursorString from memcache). a reload of the page should work. a second tap in the browser would be a problem i think...
what would you say?

Using/Searching AsyncDataProvider with Objectify / Google App Engine

I currently have an application which uses the activities/places and an AsyncDataProvider.
Right now, everytime the activity loads up - it uses the request factory to retrieve the data (currently not a lot but will get very large coming up here soon) and passes it to the View to update the DataGrid. Before it is updated it is filtered based on a search box.
Right now - I have implemented updating the DataGrid as follows: (this code isn't the prettiest)
private void updateData() {
final AsyncDataProvider<EquipmentTypeProxy> provider = new AsyncDataProvider<EquipmentTypeProxy>() {
#Override
protected void onRangeChanged(HasData<EquipmentTypeProxy> display) {
int start = display.getVisibleRange().getStart();
int end = start + display.getVisibleRange().getLength();
final List<EquipmentTypeProxy> subList = getSubList(start, end);
end = (end >= subList.size()) ? subList.size() : end;
if (subList.size() < DATAGRID_PAGE_SIZE) {
updateRowCount(subList.size(), true);
} else {
updateRowCount(data.size(), true);
}
updateRowData(start, subList);
}
private List<EquipmentTypeProxy> getSubList(int start, int end) {
final List<EquipmentTypeProxy> filteredEquipment;
if (searchString == null || searchString.equals("")) {
if (data.isEmpty() == false && data.size() > (end - start)) {
filteredEquipment = data.subList(start, end);
} else {
filteredEquipment = data;
}
} else {
filteredEquipment = new ArrayList<EquipmentTypeProxy>();
for (final EquipmentTypeProxy equipmentType : data) {
if (equipmentType.getName().contains(searchString)) {
filteredEquipment.add(equipmentType);
}
}
}
return filteredEquipment;
}
};
provider.addDataDisplay(dataGrid);
}
Ultimately - what I would like to do is only load up the necessary data at first (the default page size in this application is 25).
Unfortunately, to my current understanding, with Google App Engine there is no order to any of the Id's (one entry has an ID of 3 the next has an entry of 4203).
What I'm wondering, what is the best way to go about retrieving a subset of data from Google App Engine when using Objectify?
I was looking into using Offset and limit but another stack overflow post (http://stackoverflow.com/questions/9726232/achieve-good-paging-using-objectify) basically said this is inefficient.
The best information I've found is the following link (http://stackoverflow.com/questions/7027202/objectify-paging-with-cursors). The answer here says to use Cursors but also says this is inefficient. I'm also using Request Factory so I will have to store the Cursor in my user Session (if that is incorrect please let me know).
Currently since there isn't likely to be a lot of data (maybe 200 rows total for the next few months) I am just pulling back the entire set to the client as a temporary hack - I know this is the worst way to do it but would like to get input to the best way to do it before wasting my time implementing another hack solution. I am worried currently as it seems every single post i've read on doing this makes it seem like there's not really a solid way to do this.
What i am also thinking about doing - currently my searching / page loading is lightning fast because all the data is already on the client side. I use a KeyUpEvent handler in the search box to filter the data - i don't think there is any way to keep this speed by making a call to the server - is there any accepted solution to this problem?
Thank you very much
Go with Cursors. They are as efficient as it gets - cursor stores the point where last query ended and continues from there. The answer you linked actually does not discuss efficiency of cursors vs offset. (there is a comment that is wrong)
You can use limit with Cursors - it does not affect efficiency.
Also, Cursors can be serialized via cursor.toWebSafeString() and sent to client via RPC. This way you do not need to save them in session. Actually you can also use them as fragment identifier (aka history token in GWT parlance) - this way a certain "page" of your result set can be bookmarked.
(Offset is "inefficient" because it actually loads, and charges you, for all entities upto offset+limit, bit it only returns limit entities)
OTOH, if you already know the query parameters when the page is loaded, then just do the query at page generation time, instead invoking it via RPC. Also, if you have a small set of data (<1000) you could just preload all entity IDs s part of page html.

JCR checkin/checkout operations

I'm just starting to work with JCR (apache jackrabbit), i want to ask simple question (because i coudn't find good tutorial for it):
So for what do i need Node.checkout and Node.checkin methods?
What do they mean?
Thx
The 'checkin' and 'checkout' methods have to do with how a JCR repository tracks the versions of content. The 'checkout' method signals to the repository that your client application is (likely) going to be modifying some versionable content. The 'checkin' methods signals to the repository that your client application has made changes to the versionable content, and that the repository should record those changes (e.g., the new version) in the version history.
For example, let's imagine that we want to create a node at '/a/b/c' that is versionable. This is done using something like the following code:
To create content, you simply set the 'mix:versionable' mixin (or use a mixin or primary node type that inherits from 'mix:versionable') on a node and then save your changes. At that point, the repository will initialize the version history for that node (or subgraph).
Node b = session.getNode("/a/b");
Node newNode = b.addNode("c");
newNode.addMixin("mix:versionable");
// set other properties and create children
session.save();
Upon 'session.save()', the repository will note the 'mix:versionable' mixin and will initialize the version history for the content at '/a/b/c'. From this point on, your client application uses 'checkout' and 'checkin' to add new versions to the history.
VersionManager vm = session.getWorkspace().getVersionManager();
vm.checkout("/a/b/c");
// make some changes at/under '/a/b/c'
session.save();
// Can make more changes and save, if desired
vm.checkin("/a/b/c");
When 'checkin' is called, the repository will take the current state of '/a/b/c' and will add it to the version history. Of course, this process is repeated each time you want to make changes to versionable nodes.
In Jackrabbit 2.x, the methods on Node are deprecated. Instead, use VersionManager.checkout / checkin (they are available in Jackrabbit 1.x as well). Here is some sample code:
Node test = s.getRootNode().addNode("test");
Node t1 = test.addNode("t1");
t1.addMixin("mix:versionable");
s.save();
VersionManager vm = s.getWorkspace().
getVersionManager();
vm.checkout("/test/t1");
t1.setProperty("data", "Hello" + i);
s.save();
vm.checkin("/test/t1");

How to dynamically discover all XAML files in all modules in a Silverlight prism app

Is there an easy way to dynamically discover all the XAMLs files within all the currently loaded modules (specifically of a Silverlight Prism application)? I am sure this is possible, but not sure where to start.
This has to occur on the Silverlight client: We could of course parse the projects on the dev machine, but that would reduce the flexibility and would include unused files in the search.
Basically we want to be able to parse all XAML files in a very large Prism project (independent of loading them) to identify all localisation strings. This will let us build up an initial localisation database that includes all our resource-binding strings and also create a lookup of which XAML files they occur in (to make editing easy for translators).
Why do this?: The worst thing for translators is to change a string in one context only to find it was used elsewhere with slightly different meaning. We are enabling in-context editing of translations from within the application itself.
Update (14 Sep):
The standard method for iterating assemblies is not available to Silverlight due to security restrictions. This means the only improvement to the solution below would be to cooperate with the Prism module management if possible. If anyone wants to provide a code solution for that last part of this problem there are points available to share with you!
Follow-up:
Iterating content of XAP files in a module-base project seems like a really handy thing to be able to do for various reasons, so putting up another 100 rep to get a real answer (preferably working example code). Cheers and good luck!
Partial solution below (working but not optimal):
Below is the code I have come up with, which is a paste together of techniques from this link on Embedded resources (as suggested by Otaku) and my own iterating of the Prism Module Catalogue.
Problem 1 - all the modules are
already loaded so this is basically
having to download them all a second
time as I can't work out how to
iterate all currently loaded Prism modules.
If anyone wants to share the bounty
on this one, you still can help make
this a complete solution!
Problem 2 - There is apparently a bug
in the ResourceManager that requires
you to get the stream of a known
resource before it will let you
iterate all resource items (see note in the code below). This means I have to have a dummy resource file in every module. It would be nice to know why that initial GetStream call is required (or how to avoid it).
private void ParseAllXamlInAllModules()
{
IModuleCatalog mm = this.UnityContainer.Resolve<IModuleCatalog>();
foreach (var module in mm.Modules)
{
string xap = module.Ref;
WebClient wc = new WebClient();
wc.OpenReadCompleted += (s, args) =>
{
if (args.Error == null)
{
var resourceInfo = new StreamResourceInfo(args.Result, null);
var file = new Uri("AppManifest.xaml", UriKind.Relative);
var stream = System.Windows.Application.GetResourceStream(resourceInfo, file);
XmlReader reader = XmlReader.Create(stream.Stream);
var parts = new AssemblyPartCollection();
if (reader.Read())
{
reader.ReadStartElement();
if (reader.ReadToNextSibling("Deployment.Parts"))
{
while (reader.ReadToFollowing("AssemblyPart"))
{
parts.Add(new AssemblyPart() { Source = reader.GetAttribute("Source") });
}
}
}
foreach (var part in parts)
{
var info = new StreamResourceInfo(args.Result, null);
Assembly assy = part.Load(System.Windows.Application.GetResourceStream(info, new Uri(part.Source, UriKind.Relative)).Stream);
// Get embedded resource names
string[] resources = assy.GetManifestResourceNames();
foreach (var resource in resources)
{
if (!resource.Contains("DummyResource.xaml"))
{
// to get the actual values - create the table
var table = new Dictionary<string, Stream>();
// All resources have “.resources” in the name – so remove it
var rm = new ResourceManager(resource.Replace(".resources", String.Empty), assy);
// Seems like some issue here, but without getting any real stream next statement doesn't work....
var dummy = rm.GetStream("DummyResource.xaml");
var rs = rm.GetResourceSet(Thread.CurrentThread.CurrentUICulture, false, true);
IDictionaryEnumerator enumerator = rs.GetEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Key.ToString().EndsWith(".xaml"))
{
table.Add(enumerator.Key.ToString(), enumerator.Value as Stream);
}
}
foreach (var xaml in table)
{
TextReader xamlreader = new StreamReader(xaml.Value);
string content = xamlreader.ReadToEnd();
{
// This is where I do the actual work on the XAML content
}
}
}
}
}
}
};
// Do the actual read to trigger the above callback code
wc.OpenReadAsync(new Uri(xap, UriKind.RelativeOrAbsolute));
}
}
Use GetManifestResourceNames reflection and parse from there to get only those ending with .xaml. Here's an example of using GetManifestResourceNames: Enumerating embedded resources. Although the sample is showing how to do this with a seperate .xap, you can do this with the loaded one.
I've seen people complain about some pretty gross bugs in Prism
Disecting your problems:
Problem 1: I am not familiar with Prism but from an object-oriented perspective your Module Manager class should keep track of whether a Module has been loaded and if not already loaded allow you to recursively load other Modules using a map function on the List<Module> or whatever type Prism uses to represent assemblies abstractly. In short, have your Module Manager implement a hidden state that represents the List of Modules loaded. Your Map function should then take that List of Modules already loaded as a seed value, and give back the List of Modules that haven't been loaded. You can then either internalize the logic for a public LoadAllModules method or allow someone to iterate a public List<UnloadedModule> where UnloadedModule : Module and let them choose what to load. I would not recommend exposing both methods simultaneously due to concurrency concerns when the Module Manager is accessed via multiple threads.
Problem 2: The initial GetStream call is required because ResourceManager lazily evaluates the resources. Intuitively, my guess is the reason for this is that satellite assemblies can contain multiple locale-specific modules, and if all of these modules were loaded into memory at once it could exhaust the heap, and the fact these are unmanaged resources. You can look at the code using RedGate's .NET Reflector to determine the details. There might be a cheaper method you can call than GetStream. You might also be able to trigger it to load the assembly by tricking it by loading a resource that is in every Silverlight assembly. Try ResourceManager.GetObject("TOOLBAR_ICON") or maybe ResourceManager.GetStream("TOOLBAR_ICON") -- Note that I have not tried this and am typing this suggestion as I am about to leave for the day. My rationale for it being consistently faster than your SomeDummy.Xaml
approach is that I believe TOOLBAR_ICON is hardwired to be the zeroth resource in every assembly. Thus it will be read very early in the Stream. Faaaaaast. So it is not just avoiding needing SomeDummy.Xaml in every assembly of your project that I am suggesting; I am also recommending micro-optimizations.
If these tricks work, you should be able to significantly improve performance.
Additional thoughts:
I think you can clean up your code further.
IModuleCatalog mm = this.UnityContainer.Resolve<IModuleCatalog>();
foreach (var module in mm.Modules)
{
could be refactored to remove the reference to UnityContainer. In addition, IModuleCatalog would be instantiated via a wrapper around the List<Module> I mentioned in my reply to Problem 1. In other words, the IModuleCatalog would be a dynamic view of all loaded modules. I am assuming there is still more performance that can be pulled out of this design, but at least you are no longer dependent on Unity. That will help you better refactor your code later on for more performance gains.

Resources