Can I read the maxOccurs property for a segment from the stream being processed? - bean-io

I am trying to create a mapping file for a fixed length file that contains multiple repeating segments. Problem is, that more than one of these segments are repeated an indefinite number of times, which is not supported by beanio for flat files. I understand, that there is a good reason for this, as beanio can do only so much guesswork about how often a segment repeats.
However the number of repetitions for each segment is present in the file, at a position before the repeating segments occur, so I am trying to figure out whether there is a way to read that number from the stream and then populate the "minOccurs" and "maxOccurs" properties for the following segment with the correct value.
Basically my mapping file looks like:
<beanio>
<stream name="employeeFile" format="fixedlength">
<record name="record1" class="example.Record1">
<field name="field1" length="10"/>
<field name="field2" length="2"/>
<field name="length1" length="2"/>
<segment name="list1" collection="list" minOccurs="1" maxOccurs="unbounded" class="example.List1">
...
</segment>
<field name="length2" length="2"/>
<segment name="list2" collection="list" minOccurs="1" maxOccurs="unbounded" class="example.List2">
...
</segment>
</record>
</stream>
</beanio>
I now need some way to use the value of fields length1 and length2 as "maxOccurs" property in the segments. I am fairly certain that there is no "official" way to get this behavior, but I have so far failed to come up with an even remotely elegant solution for this.
An idea I had was to create a procedure that loads the number of repetitions for each segment from the file and then doing a search-replace on the mapping file, before loading this in beanio, however this seems like a very complicated way of doing things.
Thanks,
Sönke

Found the answer myself. I was reading the beanio reference documentation for version 2.0, not 2.1 which introduced the feature I am looking for.
The reference document states:
If a field repeats a fixed number of times based on a preceding field
in the same record, the occursRef attribute can be used to identify
the name of the controlling field. If the controlling field is not
bound to a separate property of its parent bean object, be sure to
specify ignore="true". The following mapping file shows how to
configure the accounts field occurrences to be dependent on the
numberOfAccounts field. If desired, minOccurs and maxOccurs may still
be specified to validate the referenced field occurrences value.
So one can use:
<field name="accounts" type="int" collection="list" occursRef="numberOfAccounts" />
to get the intended result.
I don't think this property works with xml streams, as it is not really needed here. I accidentally tried to add this in a mapping file and got an exception instead of a proper error message.

Related

Quickfix - Tag not defined for this message type

I'm getting an exec report from my counter party, and my quickfix engine is rejecting it for "Tag not defined for this message type 371=1300"
It seems to be saying that the exec report has a non-standard tag (1300), and my quickfix engine doesn't like it.
However, I have added that tag into my dictionary XML file, as follows
<field number="1300" name="MarketSegmentID" type="String" added="FIX.5.0" addedEP="52" abbrName="MktSegID" textId="FIELD_1300">
<enum value="BETP" symbolicName="BETP" textId="ENUM_1300_BETP"/>
<enum value="BGL" symbolicName="BGL" textId="ENUM_1300_BGL"/>
<enum value="BMTF" symbolicName="BMTF" textId="ENUM_1300_BMTF"/>
<enum value="BSEF" symbolicName="BSEF" textId="ENUM_1300_BSEF"/>
</field>
So it should know about tag 1300. My counter party sends "1300=BSEF", so it's one of the valid choices.
What exactly does "tag not defined for this message type" mean? What should I try?
There are two main sections to your XML file: (1) The message definitions, and (2) the tag definitions.
You added the tag definition, but you didn't edit the ExecutionReport message definition to include that new tag.

Difference between "group" and "component" in QuickFIX/J

I am new to the FIX world. I am writing an application processing FIX messages in Java and for that I am using QuickFIX/J. I have downloaded the DataDictionary from the homepage (http://quickfixengine.org/). I am using the version 4.4.
In the XML-file exist groups and components. But a component can contain groups again.
What's the exact difference between them?
Components aren't really... things. They're like macros in the FIX DataDictionary (DD). Many messages need the same set of fields, so instead of specifying the same fields in every message, the DD defines a component that other messages can include.
A Group, on the other hand, is a very real thing. It's a repeating sequence of fields that will appear 0 or more times in a message.
QuickFIX's (QF) programming interface largely ignores components as a concept. You can't extract a component from a message because a component isn't a concept in QF; you just extract the fields like any other field.
A hypothetical example: The following two message definitions are exactly the same.
With a component
<message name="Automobile" msgtype="X" msgcat="app">
<field name="Wheel" required="Y"/>
<field name="Bumper" required="Y"/>
<component name="Dashboard" required="Y"/>
</message>
<component name="Dashboard">
<field name="Radio" required="Y"/>
<field name="AirConditioner" required="Y"/>
<field name="Heater" required="Y"/>
</component>
Without a component
<message name="Automobile" msgtype="X" msgcat="app">
<field name="Wheel" required="Y"/>
<field name="Bumper" required="Y"/>
<field name="Radio" required="Y"/>
<field name="AirConditioner" required="Y"/>
<field name="Heater" required="Y"/>
</message>
See? A component is pretty much just a macro.
Either way it's defined, you just end up calling msg.GetHeater() (or whatever).
From the FIXWiki for Components:
Component blocks are sets of related data fields grouped together and are referenced by the component block name in messages that they are used in. Sometimes they are referred to as "Groups".
Component blocks are practical to be defined, and then reused in different message types. Sometimes a repeating group is just for one particular message and then it is not defined as a Component block.
View a component block as a reusable definition of fields. Such a component block may or may not contain a repeating group of fields.
For instance take the Parties component block which is used in many different messages types (see "Used In" on that page). Easy to define once and use in many definitions of messages.
Just going to add some information since the accepted answer is missing this information (probably due to the fact that it is about five years old now).
In QuickFIX/J you are actually able to get and set components. So you can for example simply copy the Instrument component from one message to another.
#Test
public void testComponent() throws Exception {
final Instrument instrument = new Instrument();
instrument.set(new Symbol("DELL"));
instrument.set(new CountryOfIssue("USA"));
instrument.set(new SecurityType(SecurityType.COMMON_STOCK));
final quickfix.fix44.NewOrderSingle newOrderSingle = new quickfix.fix44.NewOrderSingle();
newOrderSingle.set(instrument);
final quickfix.fix44.ExecutionReport executionReport = new quickfix.fix44.ExecutionReport();
executionReport.setComponent(newOrderSingle.getInstrument());
System.out.println("NOS: " + newOrderSingle.toString().replace('\001', '|'));
System.out.println("ER: " + executionReport.toString().replace('\001', '|'));
}
Output:
NOS: 8=FIX.4.4|9=28|35=D|55=DELL|167=CS|470=USA|10=233|
ER: 8=FIX.4.4|9=28|35=8|55=DELL|167=CS|470=USA|10=221|
Maybe this is also possible in the other QuickFIX language variants.

EdgeNGramFilterFactory change in solr5

Short version:
Does anyone knows if something happened with EdgeNGramFilterFactory for solr5? It used to work fine on solr 4, but I just upgraded to solr5 and the cores having this fields using this filter refuses to load ...
Long story:
This configuration used to work in solr4.10 (schema.xml):
<field name="NAME" type="string" indexed="true" stored="true" required="true" multiValued="false"/>
<field name="PP" type="text_prefix" indexed="true" stored="false" required="false" multiValued="false"/>
<copyField source="NAME" dest="PP">
<fieldType name="text_prefix" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15" side="front"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.KeywordTokenizerFactory"/>
</analyzer>
</fieldType>
And the documentation says I did it right (no clear mention if it is for solr4 or solr5).
However, when I am trying to add a collection using this configuration, it fails with the following message:
<lst name="failure">
<str>
org.apache.solr.client.solrj.impl.HttpSolrClient$RemoteSolrException:Error from server at http://localhost:8983/solr: Error CREATEing SolrCore 'test_collection': Unable to create core [test_collection] Caused by: Unknown parameters: {side=front}</str>
</lst>
I removed the side=front "unknown" parameter, started from scratch and it worked - meaning no more errors.
So, while it used to work for solr4 without any additional change, for solr5 it no longer works. Did something changed? Did I miss any doc regarding this filter? Any extra library I need to load to make this work?
And final, if the above is meant to be like this (bug/feature/whatever) - is there any workaround in order to have this "side-substring" indexing-functionality without me having to generate the values when I am adding docs to solr?
Update: with the "hacked" schema (i.e. without side=front), I indexed the documents and changed the PP field to be stored. when I searched, it looks like it indexes the entire value. For example, for NAME:ELEPHANT, I found PP:ELEPHANT ...
That attribute side has been removed in the context of LUCENE-3907 in Version 4.4. This filter now always behaves as if you gave in side="front". So you may just remove that attribute and are fine, since you are using it the "front-way".
As you can read in the conversation of the linked Lucene Issue
If you need reverse n-grams, you could always add a filter to do that
afterwards. There is no need to have this as separate logic in this
filter. We should split logic and keep filters as simple as possible.
And this is what has been done. The side attribute has been removed from the filter.
This has been done in Lucene, not directly in Solr. As Lucene is a Java-API it has been mentioned in the Java Doc of the filter
As of Lucene 4.4, this filter does not support
EdgeNGramTokenFilter.Side.BACK (you can use ReverseStringFilter
up-front and afterward to get the same behavior), handles
supplementary characters correctly and does not update offsets
anymore.
This may be the reason why you do not find a word about it in the Solr documentation. But this change has also been mentioned in Lucene's Change Log.

How to use the same WSDL message defenitions in multiple functions?

I had some errors about invalid definitions coming from Visual Studio 2010 when trying to call a WSDL defined function. The problem was that you cannot use the same message definition in two seperate functions. So I have to create multiple message definitions while they do the same.
For instance:
<message name="Hi">
<part name="input" type="xsd:string">
</message>
<message name="Say_hi_back">
<part name="return" type="xsd:string">
</message>
<message name="I_hate_you">
<part name="return" type="xsd:string">
</message>
<portType name="DataPort">
<operation name="sayHello">
<input message="tns:Hi"/>
<output message="tns:Say_hi_back"/>
</operation>
<operation name="sayIHateYou">
<input message="tns:Hi"/>
<output message="tns:I_hate_you"/>
</operation>
</portType>
Now calling either one of the functions will give you an error. Unless I add a Hi2 with exactly the same parts and change one of the input messages in the operation definitions to tns:Hi2.
Why is this? It makes no sense. I'm building up a service where I'm going to have to add the customerID to all the functions I'm going to build. One function for getting the appointments, one for the payments, one for all. This means I'm going to have to copy the message definition like 10 times and name them getCustomerID*N*.
Also a lot of times I'm going to have to have multiple input parameters. Say for instance someone wants to have all appointments between date x and date y. (And this goes for all the information that is stored like payments etc.) While I only need one message with an int, a date and a date. I'm going to have to write a huge document.
So my question is if there is any other way to do this. I've only been working with WSDL for two days and those were two days full of problems and deceiving 'victories'. Where you solve one problem only to find out that opened the gate to the next.
Thanks. :)
You are creating a WSDL reflecting an RPC style as evidenced by the 'type' attributes in the message part definitions. I am not entirely sure why this would cause a problem with VS, but the RPC style has gone out of vogue in favor of the document style (the modern versions of some tools have dropped support for RPC altogether).
You may have better results using the document style (document/literal/wrapped is our standard). You can read a little more about style differences here (http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/).
The changes required are not too complex and this site (http://wso2.org/library/knowledge-base/convert-rpc-encoded-wsdl-document-literal-wrapped-wsdl) gives some help, although I think the author flipped his rpc vs literal output definitions in the #Output message section.

Alfresco Share constraint default empty value

i have a simple question.
Is there a simple config file or line that can be edited in order to achieve this:
I need that constraints from Alfresco content model have an empty field (like "unselected") in Advanced Search and Edit Metadata forms.
So a constraint of:
<constraint name="custom:customList" type="LIST">
<parameter name="allowedValues">
<list>
<value>first type</value>
<value>second type</value>
</list>
</parameter>
</constraint>
I need to view these in a "SELECT" form but with the first selection empty, like:
<select>
<value></value>
<value>first type</value>
<value>second type</value>
</select>
Hope I made that clear.
P.S. I don't want to insert a in the custom content model XML file. There should be another way to achieve this.
Thanks to all.
You need to override the presentation logic, i.e. customize or create a new form control template. The default one is implemented in selectone.ftl, you can customize it or start from it for a brand new control template which you can later assign to your metadata field in the forms configuration.