Resources accessible via the DataFactory Interface - pentaho

Looking into org.pentaho.reporting.engine.classic.core.DataFactory and more specifically into the initialize method (which was formerly part of the ContextAwareDataFactory) I was wondering what resources/what part of the context is accessible via the interface, e.g. via the ResourceManager.
For instance, is it possible to get access to "resources" defined in a report, e.g. data sources or formulas (aside from the report parameters which are accessible via the query Method)? Thanks in advance!

The resource-manager allows you to access raw data stored in the zip/prpt file - but we do not allow you to access the parsed report or any of its (parsed) components.
With the resource-manager you can for instance load embedded xml- or other files and parse them as part of the query process.
If you were to do something extra nasty that requires access to the report definition and its content, then you could gain access via a wild hack using subreports:
Create a new report-function (via code). In that function, override the
"reportInitialized" method to get the report instance
("event.getState().getReportDefinition()"). Store that object in the
function and return it via the "getValue()" method of your function.
Pass that function's result as parameter to a subreport.
The subreport's data-factories can now access the parameter,
which is the report object returned by the master-report's function.
This process is intentionally complex and not fun. We are strongly against using the report in the process of querying data.
P.S: If you intent to access a SQL/MQL/MDX datasource from a scriptable datasource, then simply use the script-extensions that are built into these datasources since PRD-3.9.
http://www.sherito.org/2011/11/pentaho-reportings-metadata-datasources.html

Related

CKAN: Get user object or id when a context object is not available in extension

When writing a CKAN extension, I can create a custom GET-able method, which automatically receives the context.
e.g.
#side_effect_free
def custom_method(context, data_dict):
# Do something with the context and/or data_dict
The context argument above, which is basically injected by CKAN, contains, among other things, the user object which can be used to identify the user.
In other cases, like for example in a template helper, how can I get access to the user information? Ideally, I would like to have a context object just as above, so that I can call for example package_search and the rest of the actions provided in the toolkit.
Turns out that when calling actions, skipping the context variable will cause ckan to add it later inside the call, so there's no need to provide the context yourself. Also, if you want information on the user, the g variable from Flask has everything you need.

Is it a good practice the attach an event related parameter to an object's model as a variable?

This is about an API handling the validation during saving an object. Which means that the front-end client sends a request to the API to a specific end point, then on the back-end the API creates a new object if the right conditions are meet.
Right now the regular method that we use is that the models has a ruleset for each fields and then the validation is invoked when the save function is invoked, but technically the validation is done right before the object is saved into the database.
Then during today's code review I came across a solution which I wasn't sure if it's a good practice or not. And it was about that the front-end must send a specific parameter to the API every time. This is because other APIs are using our API as well, and we needed to know if the request was sent as and API request or a browser request. If this parameter is present then we want to execute an extra validation function on a specific field.
(1)If I would have to implement it, then I would check the incoming parameter in the service handler or in the controller level, and if I got one, I would invoke the validation right away, and if it fails I would throw an error.
(2)The implementation I saw however adds an extra variable to the model, and sets the model variable when there is an incoming parameter, then validates only when the save function is invoked on the object(which first validates the ruleset defined on the object fields, then saves the object into the database)
So my problem with (2) is that the object now grown bigger with an extra variable that is only related to a specific event. So I would say it's better to implement (1). But (2) also has an advantage, and that is when you create the object on different end point by parsing the parameters, then the validation will work there as well, even if the developer forget to update the code there.
Now this may seems like a silly question because, why would I care about just 1 extra variable, but this is like a bedrock of something good or bad. So if I say this is ok, then from now on the models will start growing with extra variables that are only related to specific events, which I think should be handled on the controller/service handler level. On the other hand the code would be more reliable if it's not the developer who should remember all the 6712537 functionalities and keep them in mind when makes some changes somewhere. Let's say all the devs will get heart attack tomorrow from the excitement of an amazing discovery, and a new developer has to work on the project while he doesn't know about these small details, and then he has to change something on the code that is related to this functionality - so that new feature should be supported by this old one as well.
So my question is if is there any good practice on this, and what do you think what would be the best approach?
So I spent some time on thinking on the solution, and I think the best is to have an array of acceptable trigger variables in the model class. Then when the parameters are passed to the model on the controller level, then the loader function can be modified that it takes the trigger variables from the parameters and save it in the model's associative array variable that stores the trigger variables.
By default this array is empty, and it doesn't matter how much new variables are needed to be created, it will only contain the necessary ones when those are used.
Then of course the loader function needs to be modified in a way that it can filter out the non trigger variables as well as it is done for the regular fields, and there can be even a rule set of validation on the trigger variables if necessary.
So this solves the problem with overgrowing the object with unnecessary variables and the centralized validation part, because now the validation can be always done in the model instead of the controller.
And since the loader function is modified to store the trigger variables in the model's trigger variables array variable, the developer never has to remember that this functionality was created. Which is good, because in the future when he creates a new related function or end point that should handle object creation, he will not miss it to validate it against the old functionality, because the the loader function that he modified in the past like this will handle it for him.
It needs to be noted tho, that since the loader function doesn't differentiate between the parameters, and where to load them other then checking the names of the parameters with the filter functions, these parameter names should be identical from each other, otherwise a buggy functionality can be created accidentally. Like if you forget that a model attribute with the same name was used, then you can accidentally trigger an event that was programmed to be triggered if the trigger variable with the same name is present. However this can be solved by prefixing the trigger variables for example.

Specifying a GeoTools read-only DataSource

Using a call such as:
DataStore dataStore = DataStoreFinder.getDataStore(map);
Is there an entry I can make to the map to make the datastore read-only? The only thing I have seen is the URL to specify the name for the datasource.
I imagine that the reason a map is used to send in arguments is that various data sources require different parameters. I am dealing with shape files right now and have not seen any way to specify it.
Thanks.
A DataStore doesn't have a notion of being read-only or read-write. On the other hand, the classes which access a feature type do; there is a difference between a FeatureSource and a FeatureStore. The former class does not have any write/update functions. A high-level description is here.
By default datastore.getFeatureSource returns its result cast as a FeatureSource (read-only). If you want to have write-access, you have to try and cast the FeatureSource to a FeatureStore. As a note, not all DataStore implementations provide write-access.

What is Injectable and Embeddable?

I have heard about both terms Injectable and Embeddable many times, but I am not getting actual meaning of it.
Please help me to understand both clearly.
Injectable means that something can be created and added to the main script while the script is running.
Embeddable means something can be added to a script or code before running it i.e before compilation or running of the script.
For better understanding lets take a website with a textbox as a context.
Now, In the textbox, suppose its very basic one. So, I can add a javascript into the textbox and when I will submit, it will run my JS script. This way, I am injecting my own script into the main page.
Now, suppose, I add an Iframe of another website to the HTML file of my website. In this way, when the website will be viewed, it contains the iframe. In this way, the Iframe is embedded to the website.
Injectable means that the object can be created and injected at run time. This is a hint to the compiler that this object will be managed outside the scope of the compilation and can be used at runtime to determine if the object was intended to be injected.
Embeddable means that the object can be serialized and stored in a column instead of as a separate table when the containing object is persisted. That also implies the lifetime of the embedded object is the same as the lifetime of the containing object.

IBM Worklight - JSONStore logic to refresh data from the server and be able to work offline

currently the JSONStore API provides a load() method that says in the documentation:
This function always stores whatever it gets back from the adapter. If
the data exists, it is duplicated in the collection". This means that
if you want to avoid duplicates by calling load() on an already
populated collection, you need to empty or drop the collection before.
But if you want to be able to keep the elements you already have in
the collection in case there is no more connectivity and your
application goes for offline mode, you also need to keep track of
these existing elements.
Since the API doesn't provide a "overwrite" option that would replace the existing elements in case the call to the adapter succeeds, I'm wondering what kind of logic should be put in place in order to manage both offline availability of data and capability to refresh at any time? It is not that obvious to manage all the failure cases by nesting the JS code due to the promises...
Thanks for your advices!
One approach to achieve this:
Use enhance to create your own load method (i.e. loadAndOverwrite). You should have access to the all the variables kept inside an JSONStore instance (collection name, adapter name, adapter load procedure name, etc. -- you will probably use those variables in the invokeProcedure step below).
Call push to make sure there are no local changes.
Call invokeProcedure to get data, all the variables you need should be provided in the context of enhance.
Find if the document already exists and then remove it. Use {push: false} so JSONStore won't track that change.
Use add to add the new/updated document. Use {push: false} so JSONStore won't track that change.
Alternatively, if the document exists you can use replace to update it.
Alternatively, you can use removeCollection and call load again to refresh the data.
There's an example that shows how to use all those API calls here.
Regarding promises, read this from InfoCenter and this from HTML5Rocks. Google can provide more information.