Custom Rascal location protocols for M3 - rascal

The Java specific M3 has these pretty location protocols like java+method, java+enum, java+variable and many more. As far as I understand these pretty locations function as aliases for "real" locations like |project://example-project/src/HelloWorld.java|(0,1,<2,3>,<4,5>), referring to a specific piece of code within that file.
I would like to create those pretty locations for my own CSS specific M3. So they should look something like css+declaration or css+ruleset. I already have the actual "real" locations which I now directly pass on to the M3 Core. But this looks really messy and you cannot tell the locations apart.
So how do link my "real" locations to these pretty locations so that they actually function within the Rascal terminal? Can someone tell me the steps required to achieve this? Or maybe show me an example? I have already looked at the implementation for the Java specific M3 but I cannot seem to get my head around it.

Great question. To register the locations such that they are resolved on the REPL and in the IDE for opening files and such you have to register them with the "name server"
import analysis::m3::Registry;
registerProject(|project://myProject|, myM3Model); // side-effect alert!
This code will use the #declarations table from your M3 model which should map your logical locs to your physical locs.
It does that like so:
void registerProject(loc project, M3 model) {
rel[str scheme, loc name, loc src] perScheme
= {<name.scheme, name, src> | <name, src> <- model#declarations};
for (str scheme <- perScheme<scheme>)
registerLocations(scheme, project.authority, (name : src | <name, src> <- perScheme[scheme]));
}
From this code you can also learn that calling registerLocations directly is also possible. This basically adds a lookup map to the lookup registry, first indexed by scheme, then by authority and finally by path name.

Related

Get child node by name in Umbraco 7.8.1

My Content structure is:
-Home (the site root node)
-About Us
-Our Sevice1
-Our Sevice2
-Our Sevice3
I created a macro for Our Services.
In macro, I want Our Sevice1, Our Sevice2, Our Sevice3...
But in the list variable About Us also come but I don't want it
I want only our service name of the child node
var list= CurrentPage.Children();
About Us also come on the list but I don't want it.
The reason that you see the About Us page in the collection is because you use the Children method.
With the Children method you ask for the direct child nodes of a parent node traversing one level down. So in this case you ask for all direct children of the home page so this works like expected.
What you are trying to achieve is a collection of of all Service nodes. To accomplish this you could do something like this.
Make sure that you have a seperated Document Type for your service nodes ( like for example doc type Service Page ).
Then you can do the following:
var servicePages = CurrentPage.ServicePages;
You can view the docs about it here:
https://our.umbraco.org/documentation/reference/querying/dynamicpublishedcontent/collections
But all of this is using dynamic syntax, this will be removed in future versions of Umbraco. So I suggest you go and use the strongly type syntax.
Then this can be changed by:
var servicePages = Model.Content.Children.Where(x => x.DocmentTypeAlias == "servicePage");
What this does is take the IPublishedContent object of the current page you are on, which is the Home Page then you take all children which has a document type alias of type servicePage.
Like #Mivaweb mentioned, it's better to not use dynamics (I think for performance in addition to being removed in the future).
However, I don't think you have to create a separate doc type, although that will work too. The predicate for the Where method should handle other expressions such as:
var servicePages = Model.Content.Children.Where(x => x.Name.StartsWith("Our Sevice"));

Manipulating location is failing because of < and > in location

I have a location
|java+class:///smallsql/database/CommandDrop|(114,115,<3,68>,<8,5>)
which I would like to convert to
|project://SmallSQL/src/smallsql/database/CommandDrop.java|(114,115,<3,68>,<8,5>).
I want to do this by using toString, then manipulate the resulting String and then apply a toLocation. However, this is failing because toString will turn < into \< and similar for >. Now toLocation will see it as a malformed URI. Anyone any idea?
If you want to manipulate a path of a location, keeping the rest the same, just do it like this:
myLoc.path = myManipulation(myLoc.path);
where myManipulation is a function.
But to me it seems you just want to resolve the logical location to a physical one:
import IO;
myLoc = resolveLocation(myLoc);
Mind you, the project's M3 model must have been registered before using analysis::m3::Registry::registerProject otherwise the resolution won't work.
You can also directly look up the path you need by looking it up in the M3 model's declarations table.

JSF Strategies For Long Lists in SelectOneMenu e.g. TimeZones

I am implementing a way for a user to specify their timezone. Nothing new there. I want to hear what people say is a good strategy for handling cases when users need to select from a list of a couple hundred choices, but might not know the correct value for it in the list right away. I know I can use something like autocomplete, but that only works if people know what they are looking for. Sure countries should be obvious but... lowest common denominator (some people are dumb... like me ;).
There are something over 400 distinct iso timezones (not including things like EST, PST, etc. which I am not including). That is a long list. It can be conveniently divided if we let the user chose the country they are in first in say, another selectonemenu. But there are more than 200 countries. So how to present 200 countries that is easy and efficient to work with?
I have already created and packaged in a jar a number of classes to read from the Olson timezone files (iso3166.tab and zone.tab) and provide arraylists of timezone and and timezonecountries, including prioritizing specified countries to the top of the list. But now I would like to maybe learn a better way to present the countries and the timezones. I did this myself since I found it an easier and cleaner way to extract and correlate country codes and timezone codes.
For your particular requirement, I can think of using a world map like you see in a Linux distro like Ubuntu centered at Greenwich. Then placing markers for the data that you have and letting the user select the nearest marker.
See Timezone selection for Ubuntu
For this you can make use the Primefaces GMAP component and add an overlay like this:
LatLng coord1 = new LatLng(36.885233, 30.702323);
PlaceResult placeResultObj1 = new new PlaceResult("660")
//Basic marker
simpleModel.addOverlay(new Marker(coord1, "Konyaalti", placeResultObj1));
PlaceResult.java
public class PlaceResult {
private String utc_offset;
public PlaceResult(String utc_offset){
this.utc_offset = utc_offset;
}
public String getUtc_offset() {
return utc_offset;
}
public void setUtc_offset(String utc_offset) {
this.utc_offset = utc_offset;
}
}
Another approach is to use the Places library from Google maps. Using that you can get the google.maps.places.PlaceResult object by various methods, I like the autocomplete feature where you can choose the city. After a city is selected you can show the utc_offset in the infowindow.
You can take a look at this demo
Currently, it seems that most of the cities don't have utc_offset already set. One of the address I found that had utc_offset was
Newy Airport Transport Shuttle in Australia. Then you can pass the off_set as a input hidden parameter to submit the value to the server.
See also:
Google Places Library

Jena throwing ConversionException when trying to cast to OntClass

I have a particular Class URI for which I am trying to get an OntClass. The model is a regular model.
I wrote some code to find out whether the right statements were in the model, and it seems that they are so I can't understand why it won't let me view this as an OntClass. (tblURI is a String passed as a method parameter)
Resource tblR = m.createResource(tblURI);
List<Statement> prp = tblR.listProperties().toList();
for(Statement s : prp)
System.out.println(s);
System.out.println(tblR.canAs(OntClass.class));
OntClass tbl = tblR.as(OntClass.class);
This is the output:
[kps:datasource/EnsembleMS#translation_stable_id, http://www.w3.org/1999/02/22-rdf-syntax-ns#type, http://www.w3.org/2002/07/owl#Class]
[kps:datasource/EnsembleMS#translation_stable_id, http://www.w3.org/1999/02/22-rdf-syntax-ns#type, http://www.w3.org/2000/01/rdf-schema#Class]
[kps:datasource/EnsembleMS#translation_stable_id, http://www.w3.org/2000/01/rdf-schema#isDefinedBy, kps:datasource/EnsembleMS]
[kps:datasource/EnsembleMS#translation_stable_id, http://www.w3.org/2000/01/rdf-schema#label, "translation_stable_id"]
false
com.hp.hpl.jena.ontology.ConversionException: Cannot convert node kps:datasource/EnsembleMS#translation_stable_id to OntClass: it does not have rdf:type owl:Class or equivalent
at com.hp.hpl.jena.ontology.impl.OntClassImpl$1.wrap(OntClassImpl.java:81)
at com.hp.hpl.jena.enhanced.EnhNode.convertTo(EnhNode.java:155)
at com.hp.hpl.jena.enhanced.EnhNode.convertTo(EnhNode.java:34)
at com.hp.hpl.jena.enhanced.Polymorphic.asInternal(Polymorphic.java:66)
at com.hp.hpl.jena.enhanced.EnhNode.as(EnhNode.java:110)
at com.KPS.myApp.exampleMethod(myApp.java:123)
Why is it throwing an exception and how can I get an OntClass for the resource with uri tblURI?
Thanks for any pointers
You don't say what kind of model m is. In particular, if m was created with the RDFS language profile, the OntModel will be looking for an rdf:type of rdfs:Class, not owl:Class. If that's not the issue, then a complete minimal (i.e. runnable) example would help.
By the way, there's another problem I can see: resource URI's in the model should be in absolute form, not abbreviated form. The fact that you've got q-name URI's in your model, like kps:datasource/EnsembleMS#translation_stable_id, suggest that something is going wrong with your prefix handling. That won't by itself cause the problem you've reported, but it's a red flag to investigate.
Update
Responding to questions:
yes, you need to be using an OntModel, otherwise it's not possible for the OntClass to know which langauge profile to use. Either create the model as OntModel in the first place:
OntModel m = modelFactory.createOntologyModel( OntModelSpec.OWL_MEM );
or wrap your plain model as an OntModel:
OntModel om = modelFactory.createOntologyModel( OntModelSpec.OWM_MEM, m );
Of course, you many use any of the model specifications, as you please, OWL_MEM is just one option.
createResource will not expand prefixes for you. So, you should expand them yourself before creating the resource:
m.createResource( m.expandPrefix( "foo:bar" ) );
Of course, this requires the prefix "foo" to be registered as a prefix. This happens automatically if you read an RDF document that defines the prefix in its syntax, but otherwise can be done manually with setNsPrefix.

Code re-use with Linq-to-Sql - Creating 'generic' look-up tables

I'm working on an application at the moment in ASP.NET MVC which has a number of look-up tables, all of the form
LookUp {
Id
Text
}
As you can see, this just maps the Id to a textual value. These are used for things such as Colours. I now have a number of these, currently 6 and probably soon to be more.
I'm trying to put together an API that can be used via AJAX to allow the user to add/list/remove values from these lookup tables, so for example I could have something like:
http://example.com/Attributes/Colours/[List/Add/Delete]
My current problem is that clearly, regardless of which lookup table I'm using, everything else happens exactly the same. So really there should be no repetition of code whatsoever.
I currently have a custom route which points to an 'AttributeController', which figures out the attribute/look-up table in question based upon the URL (ie http://example.com/Attributes/Colours/List would want the 'Colours' table). I pass the attribute (Colours - a string) and the operation (List/Add/Delete), as well as any other parameters required (say "Red" if I want to add red to the list) back to my repository where the actual work is performed.
Things start getting messy here, as at the moment I've resorted to doing a switch/case on the attribute string, which can then grab the Linq-to-Sql entity corresponding to the particular lookup table. I find this pretty dirty though as I find myself having to write the same operations on each of the look-up entities, ugh!
What I'd really like to do is have some sort of mapping, which I could simply pass in the attribute name and get out some form of generic lookup object, which I could perform the desired operations on without having to care about type.
Is there some way to do this to my Linq-To-Sql entities? I've tried making them implement a basic interface (IAttribute), which simply specifies the Id/Text properties, however doing things like this fails:
System.Data.Linq.Table<IAttribute> table = GetAttribute("Colours");
As I cannot convert System.Data.Linq.Table<Colour> to System.Data.Linq.Table<IAttribute>.
Is there a way to make these look-up tables 'generic'?
Apologies that this is a bit of a brain-dump. There's surely imformation missing here, so just let me know if you'd like any further details. Cheers!
You have 2 options.
Use Expression Trees to dynamically create your lambda expression
Use Dynamic LINQ as detailed on Scott Gu's blog
I've looked at both options and have successfully implemented Expression Trees as my preferred approach.
Here's an example function that i created: (NOT TESTED)
private static bool ValueExists<T>(String Value) where T : class
{
ParameterExpression pe = Expression.Parameter(typeof(T), "p");
Expression value = Expression.Equal(Expression.Property(pe, "ColumnName"), Expression.Constant(Value));
Expression<Func<T, bool>> predicate = Expression.Lambda<Func<T, bool>>(value, pe);
return MyDataContext.GetTable<T>().Where(predicate).Count() > 0;
}
Instead of using a switch statement, you can use a lookup dictionary. This is psuedocode-ish, but this is one way to get your table in question. You'll have to manually maintain the dictionary, but it should be much easier than a switch.
It looks like the DataContext.GetTable() method could be the answer to your problem. You can get a table if you know the type of the linq entity that you want to operate upon.
Dictionary<string, Type> lookupDict = new Dictionary<string, Type>
{
"Colour", typeof(MatchingLinqEntity)
...
}
Type entityType = lookupDict[AttributeFromRouteValue];
YourDataContext db = new YourDataContext();
var entityTable = db.GetTable(entityType);
var entity = entityTable.Single(x => x.Id == IdFromRouteValue);
// or whatever operations you need
db.SubmitChanges()
The Suteki Shop project has some very slick work in it. You could look into their implementation of IRepository<T> and IRepositoryResolver for a generic repository pattern. This really works well with an IoC container, but you could create them manually with reflection if the performance is acceptable. I'd use this route if you have or can add an IoC container to the project. You need to make sure your IoC container supports open generics if you go this route, but I'm pretty sure all the major players do.

Resources