In SmartGwtEE project I have hierarchy of DataSources described in .ds.xml files, here is some of them:
BaseElement_DS.ds.xml
<DataSource ID="BaseElement_DS" serverConstructor="com.isomorphic.jpa.JPADataSource"
beanClassName="lnudb.server.model.BaseElement">
<fields>
<field name="id" type="sequence" hidden="true" primaryKey="true" />
<field name="name" type="text" title="Name" required="true" />
<field name="dsId" type="text" title="Datasource" hidden="true"/>
</fields>
</DataSource>
Human_DS.ds.xml
<DataSource ID="Human_DS" serverConstructor="com.isomorphic.jpa.JPADataSource"
beanClassName="org.zasadnyy.lnudb.server.model.Human" inheritsFrom="BaseElement_DS"
useParentFieldOrder="true">
<fields>
<field name="surname" type="text" />
<field name="birthday" type="date" title="Birthday" required="false" />
</fields>
</DataSource>
Problem: when I try to get parent datasource id in code
String parentDsId = DataSource.get("Human_DS").getInheritsFrom();
ClassCastExeption is raised from inside of getInheritsFrom() method:
java.lang.ClassCastException: com.google.gwt.core.client.JavaScriptObject$ cannot be cast to java.lang.String
I will be grateful for any help.
This way you won't get the exception any longer:
String parentDsId = DataSource.get("Human_DS").getInheritsFrom() + "";
However, I'm not sure whether this is "ok" for your purposes. If this is not good for you, try to create a Javascript object and assign the before mentioned value to it. I hope this helps.
Related
I have the following specification for a fixed-length data file (refer to record-C type of specification, page 4)
a second part, having a length of 1,800 characters, consisting of a table of 75 elements to be used for the display of the only data present in the communication; each of these elements is constituted by a field-code
of 8 characters and by a field-value of 16 characters
It means that the first 89 characters (omitted in the above summary) are plain old fixed-length and then, for the remaining 1800, I have to take them into groups of key-value pairs each counting up to 24 characters. Blank spaces are trimmed and empty pairs are not considered in the process.
Ideally, my bean may be constructed like
public class RecordC{
private List<Pair<String, String>> table = new ArrayList<>(MAX_TABLE_SIZE); //I don't want to use Map **yet**
}
Something can be e.g. Apache Common's Pair<String,String> or anything suitable for KVP mapping.
I understand that I can create a whole TypeHandler that takes the full 1800 bytes but I wanted to exploit the power of BeanIO.
Here is what I have done so far
<record name="RECORD_C" class="it.csttech.ftt.data.beans.ftt2017.RecordC" order="3" minOccurs="1" maxOccurs="1" maxLength="2000">
<field name="tipoRecord" rid="true" at="0" ignore="true" required="true" length="1" lazy="true" literal="C" />
<field name="cfContribuente" at="1" length="16" align="left" trim="true" lazy="true" />
<field name="progressivoModulo" at="17" length="8" padding="0" align="right" trim="true" lazy="true" />
<field name="spazioDisposizioneUtente" at="25" length="3" align="left" trim="true" lazy="true" />
<field name="spazioUtente" at="53" length="20" align="left" trim="true" lazy="true" />
<field name="cfProduttoreSoftware" at="73" length="16" align="left" trim="true" lazy="true" />
<segment name="table" collection="list" lazy="true" class="org.apache.commons.lang3.tuple.ImmutablePair">
<field name="key" type="java.lang.String" at="0" length="8" trim="true" lazy="true" setter="#1" />
<field name="value" type="java.lang.String" at="8" length="16" trim="true" lazy="true" setter="#2" />
</segment>
<field name="terminatorA" at="1897" length="1" rid="true" literal="A" ignore="true" />
</record>
Unfortunately this does not work in testing. I get only a single record in the list, decoded at positions [0-7] and [8-23] instead of expected [89-113][114-???][....][....]
Question is: how do I in BeanIO declare repeating fixed-length fields?
I have currently resolved my unmarshalling problem by removing all at attributes in the RecordC specifications. As I found out, the "at" attribute is absolute to the record and not relative to the repeating segment. However this forced me to add some ignored fields in the unmarshalling at the sole cost of a few ignores.
I will test the marshalling against the official controller once I have data
Starting to learn ofbiz, I am following the tutorial here:
https://cwiki.apache.org/confluence/display/OFBIZ/OFBiz+Tutorial+-+A+Beginners+Development+Guide#OFBizTutorial-ABeginnersDevelopmentGuide-SecureYourApplicationbyAuthentication
Now I am in the step to make the list form of persons editable. In this step I need to create a service which will be used for auto-fields-service. Below I give the code which I have done.
In the controller.xml of my componenent I have created a requestMaps as follows:
<request-map uri="updatePracticePerson">
<security https="true" auth="true"/>
<event type="service" invoke="updatePracticePerson"/>
<response name="success" type="view" value="personForm"/>
<response name="error" type="view" value="personForm"/>
</request-map>
Moving now to the PracticeScreens.xml i have the following for personForm:
<screen name="personForm">
<section>
<actions>
<set field="headerItem" value="personForm"/>
<set field="titleProperty" value="PageTitlePracticePersonForm"/>
<entity-condition entity-name="Person" list="persons"/>
</actions>
<widgets>
<decorator-screen name="CommonPracticeDecorator" location="${parameters.mainDecoratorLocation}">
<decorator-section name="body">
<label text="Person List" style="h2"/>
<include-form name="ListPersons" location="component://practice/widget/PracticeForms.xml"></include-form>
</decorator-section>
</decorator-screen>
</widgets>
</section>
The above includes the ListPersons from PracticeForms.xml, which I have as :
<form name="ListPersons" type="list" list-name="persons" list-entry-name="person" target="updatePracticePerson" paginate-target="personForm">
<auto-fields-service service-name="updatePracticePerson" default-field-type="edit" map-name="person"/>
<field name="partyId"><hidden/></field>
<field name="submitButton" title="Update" widget-style="smallSubmit"><submit button-type="button"/></field>
<field name="deletePracticePerson" title="Delete Person" widget-style="buttontext">
<hyperlink target="deletePracticePerson?partyId=${person.partyId}" description="${uiLabelMap.CommonDelete}" also-hidden="false"/>
</field>
<field name="submitButton" title="${uiLabelMap.CommonUpdate}"><submit button-type="button"/></field>
</form>
If you see above the ListPersons calls the service updatePracticePerson.
inside servicedef/services.xml i have the following:
<service name="updatePracticePerson" default-entity-name="Person" engine="simple"
location="component://practice/script/org/hotwax/practice/PracticeServices.xml" invoke="updatePracticePerson" auth="true">
<description>Create a Person</description>
<auto-attributes include="pk" mode="IN" optional="false"/>
<attribute name="salutation" mode="IN" type="String" optional="true"/>
<attribute name="firstName" mode="IN" type="String" optional="false"/>
<attribute name="middleName" mode="IN" type="String" optional="true"/>
<attribute name="lastName" mode="IN" type="String" optional="false"/>
<attribute name="suffix" mode="IN" type="String" optional="true"/>
</service>
In the root of my project in the file ofbiz-component.xml i have :
<service-resource type="model" loader="main" location="servicedef/services.xml"/>
this to make sure that my service is loaded.
Although all of the above seem correct to me I get the following error :
org.ofbiz.widget.screen.ScreenRenderException: Error rendering screen [component://common/widget/CommonScreens.xml#GlobalDecorator]: java.lang.RuntimeException: Error rendering included form named [ListPersons] at location [component://practice/widget/PracticeForms.xml]: java.lang.IllegalArgumentException: Error finding Service with name updatePracticePerson for auto-fields-service in a form widget (Error rendering included form named [ListPersons] at location [component://practice/widget/PracticeForms.xml]: java.lang.IllegalArgumentException: Error finding Service with name updatePracticePerson for auto-fields-service in a form widget)
Which obviously implies that everything is not ok and there is something wrong with my service. Could you please assist on this?
Thanks in advance,
gianis
Restart OFBiz and check the logs. During startup it will show you loading your component and then the services defined in your component. You should be able to see the problem in the logs
at the end i found the answer myself.
in the file on the root of my component ofbiz-component.xml i had:
<resource-loader name="personForm" type="component"/>
when I should have:
<resource-loader name="main" type="component"/>
I have a request-map in controller as follows:
<request-map uri="processFirstForm">
<event type="java" path="org.ofbiz.learning.learning.LearningEvents"
invoke="processFirstForm" />
<response name="success" type="view" value="OneFormScreen" />
</request-map>
In controller, I defined a handler for java event as follows:
<handler name="java" type="request" class="org.ofbiz.webapp.event.JavaEventHandler"/>
I have a screen form as follows:
<form name="FirstForm" type="single" target="processFirstForm">
<field name="firstName">
<text />
</field>
<field name="lastName">
<text />
</field>
<field name="submit">
<submit />
</field>
</form>
I also have file LearningEvents.class in folder /bin/org/ofbiz/learning/learning
But i still receive a exception when i submit FirstForm form as follows:
ERROR rendering error page [/error/error.jsp], but here is the error
text: org.ofbiz.webapp.event.EventHandlerException: Error invoking
event, the class org.ofbiz.learning.learning.LearningEvents was not
found
Can anyone help me? thank a lot!
Do you have other java services or events in this component that are working fine? I trying to understand whether the problem is in this event or the whole component setup is not complete. Start from comparing your build.xml and ofbiz-component.xml with an existing one.
I'm using Castor to write out a map of user ID's to time intervals. I'm using it to save and resume progress in a lengthy task, and I'm trying to make the XML as compact as possible. My map is from string userID's to a class that contains the interval timestamps, along with additional transient data that I don't need to serialize.
I'm able to use a nested class mapping:
...
<field name="userIntervals" collection="map">
<bind-xml name="u">
<class name="org.exolab.castor.mapping.MapItem">
<field name="key" type="string"><bind-xml name="n" node="attribute"/></field>
<field name="value" type="my.package.TimeInterval"/>
</class>
</bind-xml>
</field>
...
<class name="my.package.TimeInterval">
<map-to xml="ti"/>
<field name="intervalStart" type="long"><bind-xml name="s" node="attribute"/></field>
<field name="intervalEnd" type="long"><bind-xml name="e" node="attribute"/></field>
</class>
...
And get output that looks like:
<u n="36164639"><value s="1292750896000" e="1292750896000"/></u>
What I'd like is the name, start, and end of the user in a single node like this.
<u n="36164639" s="1292750896000" e="1292750896000"/>
But I can't seem to finagle it so the start and end attributes in the "value" go in the same node as the "key". Any ideas would be greatly appreciated.
Nash,
I think to arrange the castor mapping is bit tricky.
If you want to have structure like
<u n="36164639" s="1292750896000" e="1292750896000"/>
Then you need to create a new pojo file where it will be having
all the three fields Key,intervalStart,intervalEnd.
And let the File name as KeyTimeInterval
And map it like the below.
<field name="userIntervals" collection="map">
<class name="org.exolab.castor.mapping.MapItem">
<field name="u" type="my.package.KeyTimeInterval">
<bind-xml name="u" node="element"/>
</field>
</class>
</field>
<class name="my.package.KeyTimeInterval">
<field name="key" type="String">
<bind-xml name="n" node="attribute"/></field>
<field name="intervalStart" type="long">
<bind-xml name="s" node="attribute"/></field>
<field name="intervalEnd" type="long">
<bind-xml name="e" node="attribute"/></field>
</class>
I think you should be able to use location on s and e. Try this:-
...
<class name="my.package.TimeInterval">
<map-to xml="ti"/>
<field name="intervalStart" type="long">
<bind-xml name="s" location="u" node="attribute"/>
</field>
<field name="intervalEnd" type="long">
<bind-xml name="e" location="u" node="attribute"/>
</field>
</class>
Am answering my own question here, since there is a solution that does exactly what I want, and there's actually an error in the explanation at http://www.castor.org/xml-mapping.html#Sample-3:-Using-the-container-attribute - the container attribute is exactly what's needed here.
Changing one line in the mapping:
<field name="value" type="my.package.TimeInterval" container="true"/>
did exactly what I wanted, it didn't create a subelement for the value, just mapped the fields into the existing parent element. Since then, I've used this quite a few times to map multiple-value classes into their parent.
The error of course is the documentation states you do this by setting the container attribute to false. Of course, it should be true.
I have a Solr schema that has a "url" field:
<fieldType name="url" class="solr.TextField"
positionIncrementGap="100">
</fieldType>
<fields>
<field name="id" type="string" stored="true" indexed="true"/>
<field name="url" type="url" stored="true" indexed="false"/>
<field name="chunkNum" type="long" stored="true" indexed="false"/>
<field name="origScore" type="float" stored="true" indexed="true"/>
<field name="concept" type="string" stored="true" indexed="true"/>
<field name="text" type="text" stored="true" indexed="true"
required="true"/>
<field name="title" type="text" stored="true" indexed="true"/>
<field name="origDoctype" type="string" stored="true" indexed="true"/>
<field name="keywords" type="string" stored="true" indexed="true"/>
</fields>
<uniqueKey>id</uniqueKey>
<defaultSearchField>text</defaultSearchField>
<solrQueryParser defaultOperator="OR"/>
I can add SolrInputDocuments with all the fields and query them back using the text field and/or with a filter query on "concept". But when I try to query a specific url, I don't get any results. My code looks like:
SolrQuery query = new SolrQuery();
query.setQuery("url:" + ClientUtils.escapeQueryChars(url));
//query.setQuery("*:*");
//query.addFilterQuery("url:" + ClientUtils.escapeQueryChars(url));
List<Chunk> retCode = null;
try
{
QueryResponse resp = solrServer.query(query);
SolrDocumentList docs = resp.getResults();
retCode = new ArrayList<Chunk>(docs.size());
for (SolrDocument doc : docs)
{
LOG.debug("got doc " + doc);
Chunk chunk = new Chunk(doc);
retCode.add(chunk);
}
}
catch (SolrServerException e)
{
LOG.error("caught a server exception", e);
}
return retCode;
I've tried with and without the ClientUtils.escapeQueryChars and I've tried using a query of "url:" or a filter query on url. I never get anything back. Any hints?
Whats the actual type of "url"? In your schema.xml you should have a set of "fieldType" elements which list the actual Solr backing classes and filters that make up a data type.
For your "fieldType" for the "url" you are interested in the "class" attribute. E.g. the most basic free-text type has a class="solr.TextField". You might be using a type that has some wacky filters on it and Lucene/Solr ends up indexing your data differently from what you would expect.
Download Luke and look at your index visually:
http://www.getopt.org/luke/
It will help you "look" at your data - like I said, maybe its stored differently than what you expect.
Dammit, another stupid one on my part: Thanks to Cody's suggestion of using Luke, I discovered this inconvenient part of the schema:
<field name="url" type="url" stored="true" indexed="false"/>
Changing that to indexed="true" fixed the problem.