A bizarre dream
Well today in the classic Saturday nap the afternoon I had a dream very bizarre, bordering on the surreal, which I will relate here because the truth would not forget it will be very difficult to tell, so I apologize in advance for the horrors of writing.
The dream begins with me standing in line at an airport, really do not know where, but as I was somewhere Soviet front of me was a German and an endless line of passengers waiting for something, surely the security check point, but I saw no arc or metal detector, the line was formed with the classic tape fences zigzag as in any airport, and also behind me was a long line of people. The line itself was static, and I was talking to the German language do not remember but we were having a conversation flowing and insignificant about the country and how we enjoyed the trip.
Suddenly some people come in suits, black suit and some other dark brown, so if sunglasses and quite high, wondering if any of us wanted to buy something in the Duty Free shops. The person behind me, I mentioned one of the suits you would like to buy a couple of bottles of alcohol to lead his country at that time the Lord brought a wife put on her wrist, and he put the other in yours, so they were bound, and led him back another man said the same interest and the other gentleman dressed did the same, handcuffed him and took him. At that time the German language, I said something like "it is amazing the control you have on the alcohol here," and I mentioned something like "yes, definitely have very strict rules." Therein began
row to move, but very fast, I was following the German to a fast trot, and suddenly I started to run because everyone was very fast, even was moving so fast that I continued the line and began to spend less than flat tapes because they were already empty. The next scene was sort of waiting room chairs ergonomic orange plastic media, like the style of a classroom, the German sat in front of me, and I told her something like "going to be great fly on a Russian airline, I've never gone to any of their aircraft, "without even turning the back I said" yes, I knew I have the new aircraft Zero " (Note that the Zero fighter planes are the second world war), I asked confused "Zero? As are those?" Head slightly tilted back and it was like talking to the ceiling "are like a DC- 9, two engines, and came forward.
I took a magazine and started reading it, of course I could not see anything, no photos or letters (I hate that it happens in dreams), but suddenly about a friend, we will call M, and I mentioned "see me, I'm taking a shortcut but we will not get to board, I run with it and entered a hallway. The hall was more like a tunnel, had a rail in the middle and we were walking down a small platform on the right bank, we were talking several things, which really do not remember, and suddenly the tunnel widens, to be very large as a quarter, supported by columns, but with fairly low ceiling, and full of rails everywhere, even some trains were detained and many others walked the distance. M
I mentioned "beware of the guide bars, do not touch that zap you" and started to jump around between tracks, at first were parallel, all roads heading towards the same direction, but soon there were other cross , then diagonally, until it reached a point that everything looked like a spider web of roads, and had then so little separation between those who started walking on tiptoe so as not to touch them. Suddenly I see a kind of Y where it begins to branch a corridor, it no roads, and say "come here, we sure faster."
walked down the aisle, and the background is a passport control point, with several police officers attending to the passengers, the problem is that we get behind, that is, we saw the police sitting back, and other travelers side of the desks, M tells me "we can not go out there, come over here" and swerved slightly to the left, where a glass door, go through it, and came to a hallway and more stylish airport bien iluminado, con macetas con plantas y demás, el punto de control nos quedaba a mano derecha pero tomamos por la izquierda dirigiéndonos a otra puerta de cristal. Ella se detuvo justo enfrente de la puerta, y me dice "Espera, voy al baño", y se dirige hacia el otro lado, hacia el punto de control, en eso, había una persona de intendencia y le dice un piropo en español, algo así como "Mamacita, etc etc" y yo le respondo en voz alta "Tranquilo wey, que hablamos español", el me voltea a ver con despecho, baja la cabeza, y sigue limpiando.
M se pierde un poco después del punto de control, y vuelve a regresar, como si hubiera ido al baño instantaneamente, pero en mi sueño, aunque the still recognized as my friend and I did not notice any change, physically looked like another friend, D, and said nothing, we crossed the glass door, and I took a luggage cart, the kind of airport, and walked a little even more lit hallway, and had no roof, they saw a clear sky with clouds in the distance.
walked a short distance and began to see many tents in the middle of the corridor, they were all red, and out of them had several kids sleeping in sleeping bags just outside of them, all were red or purple sleepings. At first we were sacándoles back, me with my cart and everything, but after I loaded the cart and we were jumping between sleepings. We were also talking
D and I do not remember that stuff, but very comfortable, while the sleeping brincábamos and I in my thoughts trying to maintain balance with the cart to fall and I was not going to disgrace the face and someone's dream. Suddenly everything fades to white, and the next scene, I was viewing the aircraft, flying, was a kind of DC-10, the line was blue and the rest of the plane was white, one of the windows had a slightly darker edge, and that's what I hear the voice of D (not seen her or anyone else, only saw the plane flying in the sky), "Hey, as we did for ourselves from outside? "and I replied" no. "
woke up, and the truth is I was very engraving, not transcendence or what meaning it may have, but it is not fun: P
Saturday, February 27, 2010
Wednesday, February 24, 2010
How Do U Stop An Obsession?
A DSL for a tool Importing data
Continuing with Our opentaps examples, we want to generate data for Our Some seed application, the good thing is the OFBiz framework That Offers Some tooling to import data nice and easy, the not so nice part of it, Is That It Must Be done using xml files , like the example below: The
First of all, lets organize how we are going to import the data:
The fields will have the following meaning:
The fields have the following meaning:
This class will allow us to parse our DSL and actually create a list of nodes that will help us parse a Calc file and get all data about them, so a Groovy code using that DSL would look like this:
So now that we have the template ready, lets create now the domain model to store in memory the data parsed, first we will create an OfbizEntity class that will store the generic data about our entity:
The class will store the name of the entity, and the order in which it should be stored in the xml file, and of course a set of OfbizData objects which will have the data we will store, and will have the following code in it:
So now we will create a class named ODSReader that will read our spreadsheet and create our model in memory:
So now we can load the data in our calc file, to memory, now it is time to persist it in an Xml file, for that we will help ourselves with the excellent groovy StreamingMarkupBuilder, so lets create our OfbizEntityGenerator groovy class:
So the complete usage example of our DSL and utils would be like this:
And having the following ods file:
It will generate the following xml file:
Cool isn't it? now try to do it with a spreadsheet with a couple thousand rows, and you will see the real benefit of this.
Now tell OpenTaps that you have a new file, copy the xml (for our example it will be named products.xml) and paste it into your hot-deploy/citsaProduct/data folder and edit your ofbiz-component.xml to add the following line
Finally, to tell OpenTaps to load it, just run the following script in your opentaps home:
java -Xmx384M -jar ofbiz.jar -install -readers=ext
And voilá, you can load a ton of seed data without much effort
More references:
Continuing with Our opentaps examples, we want to generate data for Our Some seed application, the good thing is the OFBiz framework That Offers Some tooling to import data nice and easy, the not so nice part of it, Is That It Must Be done using xml files , like the example below: The
This will insert a new Product entity (or update an existing one, if the primary key already exists), modifying the fields described in the attributes of the product tag (productId, productTypeId, productName, etc.), and will also modify or create a ProductPrice entity. It sounds pretty simple (and it really is), but to be honest, what would happen if we want to have a huge amount of data, and also provided by people that isn't exactly technical, it would be really hard to write all that xml, so lets use the power of groovy and a few more tools, to create a DSL that will help us parse an spreadsheet file (in this case OpenOffice calc) and automatically generate the data xml we need.
\u0026lt;entity-engine-xml>
\u0026lt;Product product = "SUPPLY-001" ProductType = "SUPPLIES" productName = "Pencil" InternalName = "Pencil" description = "Office pencil (demo supply)."
taxable="N" chargeShipping="N" autoCreateKeywords="N" isVirtual="N" isVariant="N" createdDate="2007-01-01 00:00:00.000" createdByUserLogin="admin"/>
<ProductPrice productId="service1" productPriceTypeId="DEFAULT_PRICE" productPricePurposeId="PURCHASE" currencyUomId="USD" productStoreGroupId="_NA_" fromDate="2008-01-01 00:00:00" price="10.00"/>
</entity-engine-xml>
First of all, lets organize how we are going to import the data:
- Data will be located in an OpenOffice Calc file, each sheet will represent one or more entities
- Each column will correspond to one field (or more) of our entity
- Each row will be a complete object
- Our DSL will help us determine how our sheet will be parsed to generate an OO representation
- Then we will export that OO representation into xml files
- Groovy, I really used Grails because I wanted to make an small app with a nice frontend for the conversion
- JOpenDocument so we can parse OpenOffice Calc files in a nice way
- OpenTaps, so we can test our data files
public class ODSNode {
//Constants we will use later
public static final String SHEET_NAME_ATTR="name";
public static final String OFBIZ_NAME_ATTR="entity";
public static final String START_ROW_ATTR="startRow";
private int startRow=1;
private int index=0;
private String sheetName;
private String ofbizEntity;
private List<ODSElement> elements = new ArrayList<ODSElement>();
//getters and setters here...
}
The fields will have the following meaning:
- startRow -> This is the row at which we will start parsing to get the data from the sheet
- index -> The order in which the results will be put, so maybe some data in other sheets will have precedence than this one
- sheetName -> The name of the sheet we will be parsing
- ofbizEntity -> The name of the entity we will be populating from the data parsed
public class ODSElement {
//Some constants we will use later
public static final String COLUMN_ATTR="name";
public static final String INDEX_ATTR="index";
public static final String OFBIZ_ATTR="attribute";
public static final String CONSTANT="constant";
private String columnName;
private int columnIndex;
private Object constant;
private String ofbizColumn;
}
The fields have the following meaning:
- columnName -> I'm not using it right now, just as a placeholder to be aware of which column I'm modifying
- columnIndex -> The corresponding location of the column inside the sheet
- constant -> In some cases we won't parse information from the spreadsheet and we will insert a constant value for all the rows in our entity
- ofbizColumn -> This is the real name of the column or entity attribute for the Ofbiz Framework
public class ODSOfbizBuilder extends BuilderSupport{
private List<ODSNode> nodes = new ArrayList<ODSNnode>();
private static final String SHEET_NODE ="sheet";
private static final String COLUMN_NODE ="column";
//Return the list of nodes generated by this builder
public List<ODSNode> getNodes() {
return nodes;
}
//Create the corresponding node or element
@SuppressWarnings("unchecked")
@Override
protected Object createNode(Object name, Map attributes) {
System.out.println(name+" "+attributes);
Object obj=null;
if(name.equals(SHEET_NODE)){
ODSNode node = new ODSNode();
node.setSheetName(attributes.get(ODSNode.SHEET_NAME_ATTR).toString());
node.setOfbizEntity(attributes.get(ODSNode.OFBIZ_NAME_ATTR).toString());
if(attributes.containsKey(ODSNode.START_ROW_ATTR)){
node.setStartRow(Integer.parseInt(attributes.get(ODSNode.START_ROW_ATTR).toString()));
}
obj = node;
nodes.add(node);
}
else if(name.equals(COLUMN_NODE)){
ODSElement element = new ODSElement();
element.setColumnIndex(Integer.parseInt(attributes.get(ODSElement.INDEX_ATTR).toString()));
element.setColumnName(attributes.get(ODSElement.COLUMN_ATTR).toString());
element.setOfbizColumn(attributes.get(ODSElement.OFBIZ_ATTR).toString());
if(attributes.containsKey(ODSElement.CONSTANT)){
element.setConstant(attributes.get(ODSElement.CONSTANT));
}
obj =element;
}
else{
throw new IllegalArgumentException("Nodes must be named "+SHEET_NODE+" or "+COLUMN_NODE);
}
return obj;
}
//Add the elements to the corresponding node
@Override
protected void setParent(Object parent, Object node) {
if(parent instanceof ODSNode && node instanceof ODSElement){
((ODSNode) parent).addElement((ODSElement) node);
}
}
}
This class will allow us to parse our DSL and actually create a list of nodes that will help us parse a Calc file and get all data about them, so a Groovy code using that DSL would look like this:
def builder = new ODSOfbizBuilder()
builder.base{
sheet(name:'CatalogoUnidades',entity:"Uom",index:0){
column(name:"Constante",index:-1,attribute:"uomTypeId",constant:"WEIGHT_MEASURE")
column(name:"Unidad",index:0,attribute:"description")
column(name:"Simbolo",index:1,attribute:"abbreviation")
column(name:"ID",index:2,attribute:"uomId")
}
}
So now that we have the template ready, lets create now the domain model to store in memory the data parsed, first we will create an OfbizEntity class that will store the generic data about our entity:
public class OfbizEntity implements Comparable<OfbizEntity>{
private String entity;
private int index;
private Set<OfbizData> data = new TreeSet<OfbizData>();
//Getters and setters here
}
The class will store the name of the entity, and the order in which it should be stored in the xml file, and of course a set of OfbizData objects which will have the data we will store, and will have the following code in it:
public class OfbizData implements Comparable<OfbizData>{
private String attribute;
private String value;
//getters and setters here
}
So now we will create a class named ODSReader that will read our spreadsheet and create our model in memory:
public class ODSReader {
public List<OfbizEntity> parseFile(File spreadsheetFile,ODSOfbizBuilder builder) throws IOException{
//Here we will store all our data
List<OfbizEntity> data = new ArrayList<OfbizEntity>();
//Let's open the Calc file
SpreadSheet spreadSheet = SpreadSheet.createFromFile(spreadsheetFile);
//Let's get the nodes we parsed from our builder earlier
List<ODSNode> nodes = builder.getNodes();
for(ODSNode node : nodes){
//We need to get the sheet referenced by its name
Sheet sheet = spreadSheet.getSheet(node.getSheetName());
if(sheet == null){
throw new IllegalArgumentException("Sheet with name "+node.getSheetName()+" not found");
}
//lets get the last row with data
int lastRow = sheet.getRowCount();
int startRow = node.getStartRow();
int valueCount = 0;
//for each of the parsed sheets we need the collection of entities
Set<OfbizEntity> entities = new TreeSet<OfbizEntity>();
for(int row = startRow;row<lastrow;row++){ valuecount="0;" ofbizentity="" entity="new" odselement="" element="" string="" if="" column="" is="" a="" we="" just="" put="" the="" constant="" value="" in="" there=""> <0||element.getconstant()!=null){ value =" element.getConstant().toString();" cell =" sheet.getCellAt(element.getColumnIndex()," value="cell.getValue().toString();" tuple =" new"> 0&&valueCount>0){
entities.add(entity);
}
}
//We used a set to ensure there are no duplicates and now we add all its elements to our list
data.addAll(entities);
}
return data;
}
}
So now we can load the data in our calc file, to memory, now it is time to persist it in an Xml file, for that we will help ourselves with the excellent groovy StreamingMarkupBuilder, so lets create our OfbizEntityGenerator groovy class:
lass OfbizEntityGenerator {
String output="outputDemoData.xml"
//We receive the list of entities and parse them into an xml file
public StreamingMarkupBuilder generateOfBizDataModel(List<OfbizEntity> entities){
StreamingMarkupBuilder builder = new StreamingMarkupBuilder()
println entities.size()
def writable = builder.bind{
"entity-engine-xml"{
entities.each{
ent ->
//Here we write a comment for our entity
mkp.comment("Data for entity ${ent.entity}")
//We write the entity with its attributes
"${ent.entity}"(asMap(ent))
}
}
}
def outputString = indentXml(writable)
//And finally we write it to a physical file
def file = new FileWriter(output)
file.write(outputString)
file.flush()
file.close()
}
//We just convert our list of objects to a map, not very elegant to be honest
Map asMap(OfbizEntity entity){
def map = [:]
entity.data.each{
node ->
map[node.attribute] = node.value
}
return map
}
//We use this helper method to have a nice indentation of our xml file
String indentXml(xml) {
def factory = TransformerFactory.newInstance()
factory.setAttribute("indent-number", 2);
Transformer transformer = factory.newTransformer()
transformer.setOutputProperty(OutputKeys.INDENT, 'yes')
StreamResult result = new StreamResult(new StringWriter())
transformer.transform(new StreamSource(new ByteArrayInputStream(xml.toString().bytes)), result)
return result.writer.toString()
}
}
So the complete usage example of our DSL and utils would be like this:
def reader = new ODSReader()
File file = new File("/citsa/opentaps/myfile.ods");
def builder = new ODSOfbizBuilder()
builder.base{
sheet(name:'CatalogoUnidades',entity:"Uom",index:0){
column(name:"Constante",index:-1,attribute:"uomTypeId",constant:"WEIGHT_MEASURE")
column(name:"Unidad",index:0,attribute:"description")
column(name:"Simbolo",index:1,attribute:"abbreviation")
column(name:"ID",index:2,attribute:"uomId")
}
}
def result = reader.parseFile(file, builder)
OfbizEntityGenerator generator = new OfbizEntityGenerator()
generator.output = "products.xml"
generator.generateOfBizDataModel(result)
And having the following ods file:
It will generate the following xml file:
<?xml version="1.0" encoding="UTF-8"?>
<entity-engine-xml>
<Uom abbreviation="g" description="gramo" uomId="1.0" uomTypeId="WEIGHT_MEASURE"/>
<Uom abbreviation="lb" description="libra" uomId="2.0" uomTypeId="WEIGHT_MEASURE"/>
<Uom abbreviation="kg" description="kilogramo" uomId="3.0" uomTypeId="WEIGHT_MEASURE"/>
<Uom abbreviation="M" description="miles de semilas" uomId="4.0" uomTypeId="WEIGHT_MEASURE"/>
<Uom abbreviation="ml" description="mililitro" uomId="5.0" uomTypeId="WEIGHT_MEASURE"/>
<Uom abbreviation="l" description="litro" uomId="6.0" uomTypeId="WEIGHT_MEASURE"/>
<Uom abbreviation="docena" description="docena" uomId="7.0" uomTypeId="WEIGHT_MEASURE"/>
</entity-engine-xml>
Cool isn't it? now try to do it with a spreadsheet with a couple thousand rows, and you will see the real benefit of this.
Now tell OpenTaps that you have a new file, copy the xml (for our example it will be named products.xml) and paste it into your hot-deploy/citsaProduct/data folder and edit your ofbiz-component.xml to add the following line
<entity-resource type="data" reader-name="ext" loader="main" location="data/products.xml"/>
Finally, to tell OpenTaps to load it, just run the following script in your opentaps home:
java -Xmx384M -jar ofbiz.jar -install -readers=ext
And voilá, you can load a ton of seed data without much effort
More references:
Propeller Hat Brisbane
Modifying and Creating new data entities (opentaps)
So now we will create some new data entities for our OpenTaps installation.
Our main products are seeds, and, as you already know, they are living beings that need some special care and control while handling them. Not all seeds grow and some may die as time passes, so we need to control the germination rate of the seeds we handle.
Each variety of seed has different tolerances for the germination rate, so, some kind of seeds may be sold with a 99% of germination rate, while others would be ok with just an 80%. So we need a new field for our product entity to handle the minimum germination rate accepted for each of our products.
So we will create two new files in our citsaProduct module:
As simple as that, we use the tag extend-entity to add new fields and keys to an existing entity, in this case, we are adding a new field named germinationRate with a data type of fixed-point
Look at how the data types don't look like SQL data types, the framework has some common or generic definitions that will be translated to true SQL data types at runtime, you can look the real data types by looking at the xmls located in the folder /opentaps-1.4/framework/entity/fieldtype
Now we want to make a new entity named "Package", just to make an example on how to create new entities, so lets modify again our entitymodel.xml file and add the following text:
As a last step, we will need to modify the file ofbiz-component.xml of our module, so we can tell the Ofbiz Framework to load our new data entities:
After all this steps we should run the following script:
ant make-base-entities
This will generate Hibernate entity files in the folder hot-deploy/opentaps-common/src/entities that we will later use in our code
Finally, we just need to restart our server, and it should alter the Product table and create a new table named "Package"
So now we will create some new data entities for our OpenTaps installation.
Our main products are seeds, and, as you already know, they are living beings that need some special care and control while handling them. Not all seeds grow and some may die as time passes, so we need to control the germination rate of the seeds we handle.
Each variety of seed has different tolerances for the germination rate, so, some kind of seeds may be sold with a 99% of germination rate, while others would be ok with just an 80%. So we need a new field for our product entity to handle the minimum germination rate accepted for each of our products.
So we will create two new files in our citsaProduct module:
- entitymodel.xml -> Here we will describe our new entities, and their data types and fields
- entitygroup.xml -> Here we will configure entity groups, it usually works if we want to use different databases for our entities, but for now we will use only one database.
<?xml version="1.0" encoding="UTF-8"?>
<entitymodel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.ofbiz.org/dtds/entitymodel.xsd">
<extend-entity entity-name="Product">
<field name="germinationRate" type="fixed-point"/>
</extend-entity>
</entitymodel>
As simple as that, we use the tag extend-entity to add new fields and keys to an existing entity, in this case, we are adding a new field named germinationRate with a data type of fixed-point
Look at how the data types don't look like SQL data types, the framework has some common or generic definitions that will be translated to true SQL data types at runtime, you can look the real data types by looking at the xmls located in the folder /opentaps-1.4/framework/entity/fieldtype
Now we want to make a new entity named "Package", just to make an example on how to create new entities, so lets modify again our entitymodel.xml file and add the following text:
Finally, we have to modify the entitygroup.xml file to tell it to recognize our new Package entity:
<?xml version="1.0" encoding="UTF-8"?>
<entitymodel xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi
: noNamespaceSchemaLocation = "http://www.ofbiz.org/dtds/entitymodel.xsd">
\u0026lt;entity entity -name = "package" package-name = "org.ofbiz.citsa">
\u0026lt;field name="packageTypeId" type="id-ne"/>
\u0026lt;field name = "name" type = "name" />
\u0026lt;field name="shortName" type="name"/>
\u0026lt;prim-key field="packageTypeId"/>
\u0026lt;/ entity>
\u0026lt;extend entity-entity-name = "Product ">
\u0026lt;field name="germinationRate" type="fixed-point"/>
</extend-entity>
</entitymodel>
<?xml version="1.0" encoding="UTF-8"?>
<entitygroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.ofbiz.org/dtds/entitygroup.xsd">
<entity-group entity="Package" group="org.ofbiz"/>
</entitygroup>
As a last step, we will need to modify the file ofbiz-component.xml of our module, so we can tell the Ofbiz Framework to load our new data entities:
<?xml version="1.0" encoding="UTF-8" ?>
<ofbiz-component name="citsaProduct"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.ofbiz.org/dtds/ofbiz-component.xsd">
<resource-loader name="main" type="component"/>
<classpath location="build/classes/*" type="dir"/>
<classpath location="config" type="dir"/>
<entity-resource loader="main" location="entitydef/entitymodel.xml" reader-name="main" type="model"/>
<entity-resource loader="main" location="entitydef/entitygroup.xml" reader-name="main" type="group"/>
</ofbiz-component>
After all this steps we should run the following script:
ant make-base-entities
This will generate Hibernate entity files in the folder hot-deploy/opentaps-common/src/entities that we will later use in our code
Finally, we just need to restart our server, and it should alter the Product table and create a new table named "Package"
Best Way To Preserve Air Jordans
Creating a new module (opentaps)
Welcome to my new blog, I hope Blogger offers a better interface and tools than Roller, so, let's get started with a new series of OpenTaps entries, this will be a little more focused on customizing an existing instance of Opentaps, while trying to guarantee some code independence so you can gracefully upgrade to new versions without much trouble.
Just a little quick introduction, the customization I'm making is for my family business, which is a seed trading company, so while its business model is quite common, it has a few differences that make it interesting and a nice example to use for our exercises.
So, first of all, we are going to work with the Product module, we don't want to directly modify it so we will make a new module based on it, to do this, we will make a folder in the hot-deploy directory, and for this example we will name it citsaProduct :
On it, we will create the following new files and folders:
The resource-loader tag helps us have a common base from where to look for the files that we configure here
The classpath tag will tell the Ofbiz Framework (in which OpenTaps is based on) where to find java classes, jars and other configuration files and put them in the classpath.
We also have to tell the Ofbiz Framework to load the module at application start, so we need to modify the file hot-deploy/component-load.xml
2010-02-11 16:04:30,113 (main) [ ComponentContainer.java:218:INFO ] Loading component : [citsaProduct]
So that means that our module is loading
Welcome to my new blog, I hope Blogger offers a better interface and tools than Roller, so, let's get started with a new series of OpenTaps entries, this will be a little more focused on customizing an existing instance of Opentaps, while trying to guarantee some code independence so you can gracefully upgrade to new versions without much trouble.
Just a little quick introduction, the customization I'm making is for my family business, which is a seed trading company, so while its business model is quite common, it has a few differences that make it interesting and a nice example to use for our exercises.
So, first of all, we are going to work with the Product module, we don't want to directly modify it so we will make a new module based on it, to do this, we will make a folder in the hot-deploy directory, and for this example we will name it citsaProduct :
On it, we will create the following new files and folders: - ofbiz-component.xml -> This file contains all our main configuration of our new module, basically where to load the services, webapps, data, etc.
- build.xml -> This file contains the Ant configuration to compile and build our module, for now, copy the build.xml from the application/party module, and it should be enough
- src (folder) -> Our java sources will be located here, although for now it will be empty
- data (folder) -> Here we will put our custom seed data, in a later blog post I'll show how to create a small app to quickly create this data from a spreadsheet file
- entitydef (folder) -> Here we will put the configuration of our new and custom data entities
<?xml version="1.0" encoding="UTF-8" ?>
<ofbiz-component name="citsaProduct"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.ofbiz.org/dtds/ofbiz-component.xsd">
<resource-loader name="main" type="component"/>
<classpath location="build/classes/*" type="dir"/>
<classpath location="config" type="dir"/>
</ofbiz-component>
The resource-loader tag helps us have a common base from where to look for the files that we configure here
The classpath tag will tell the Ofbiz Framework (in which OpenTaps is based on) where to find java classes, jars and other configuration files and put them in the classpath.
We also have to tell the Ofbiz Framework to load the module at application start, so we need to modify the file hot-deploy/component-load.xml
So you should be able to run startofbiz.sh and look in the logs for an entry like this:
<component-loader xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/component-loader.xsd">
<load-component component-location="opentaps-common"/>
<load-component component-location="crmsfa"/>
<!-- Some more components here.... -->
<!-- CITSA -->
<load-component component-location="citsaProduct"/>
</component-loader>
2010-02-11 16:04:30,113 (main) [ ComponentContainer.java:218:INFO ] Loading component : [citsaProduct]
So that means that our module is loading
Tuesday, February 23, 2010
How To Mix Up Pokemon
As Chihuahueño
Very distinguished Don Herman,
Serve this at all, to thank you for taking the time to read my letter and answer all criticism, only then grows in the craft of writing and as a human being.
perceived in his column as an attack "against Valencia Chihuahua," I do not mean the devices that could use a northerner to seduce a English, but the ferocity with which the dogs of that breed (not the Don Juan Northern State in question) who attacked them on regardless of whether the intention is good, bad or just regular plane ... or even unintentionally. I believe that thousands of readers will be left only with the image of a bitter fool and a very limited repertoire of expletives (one tells you, that fact and just used it and never snapped at you) and concern know that have said that "dude", lacking "intellectual breadth and depth, which made both" enmohinar "Dehesa Dixit, a winner as a columnist. I would appreciate your
use such a prestigious place in the middle so that both the letter I sent initially (which was the one put together weaning) as well as this, my reply, are published and readers become aware fully of the "totality Letters on the facts, "" to see if it's so macho? "as would a" taster creadillas "(apologies for such a weak comment of irony ... I admit my lack of" intellectual breadth and depth, but I could not help).
Finally, you say "(this is for Schwarz squirm with envy as tlaconete salt)" to show off his friendship with Mrs. Fernanda Angeles Mastreta and Family, about her friendship with Mrs. Angeles, his analogy has fallen short, a "tlaconete with salt" would be "a gringo Mexican beach" compared with envy I feel at not having such beautiful, intelligent, bright woman much class as a friend, that friendship the envy ... with envy of the poor, which is good. About
Fernanda Familiar, starring his zeal, his narcissism and ambition (Fernanda not you), I do not generate any feelings (envy o lujuria) del cual tuviera que ir a confesarme con Pedro Picapiedra… perdón con Don Norberto Rivera (de los apodos por Usted “atizados” es el que más me gusta).
Reciba el cordial saludo de un lector “carente de amplitud y hondura intelectual “ , con muy reducido repertorio de palabrotas pero ferviente seguidor de su columna, desde antes que “el tamal de dulce” llegara a su vida como padre y a la nuestra como sus lectores.
Atentamente
Efrén Schwarz a(Chuarcito el niño héroe)
Very distinguished Don Herman,
Serve this at all, to thank you for taking the time to read my letter and answer all criticism, only then grows in the craft of writing and as a human being.
perceived in his column as an attack "against Valencia Chihuahua," I do not mean the devices that could use a northerner to seduce a English, but the ferocity with which the dogs of that breed (not the Don Juan Northern State in question) who attacked them on regardless of whether the intention is good, bad or just regular plane ... or even unintentionally. I believe that thousands of readers will be left only with the image of a bitter fool and a very limited repertoire of expletives (one tells you, that fact and just used it and never snapped at you) and concern know that have said that "dude", lacking "intellectual breadth and depth, which made both" enmohinar "Dehesa Dixit, a winner as a columnist. I would appreciate your
use such a prestigious place in the middle so that both the letter I sent initially (which was the one put together weaning) as well as this, my reply, are published and readers become aware fully of the "totality Letters on the facts, "" to see if it's so macho? "as would a" taster creadillas "(apologies for such a weak comment of irony ... I admit my lack of" intellectual breadth and depth, but I could not help).
Finally, you say "(this is for Schwarz squirm with envy as tlaconete salt)" to show off his friendship with Mrs. Fernanda Angeles Mastreta and Family, about her friendship with Mrs. Angeles, his analogy has fallen short, a "tlaconete with salt" would be "a gringo Mexican beach" compared with envy I feel at not having such beautiful, intelligent, bright woman much class as a friend, that friendship the envy ... with envy of the poor, which is good. About
Fernanda Familiar, starring his zeal, his narcissism and ambition (Fernanda not you), I do not generate any feelings (envy o lujuria) del cual tuviera que ir a confesarme con Pedro Picapiedra… perdón con Don Norberto Rivera (de los apodos por Usted “atizados” es el que más me gusta).
Reciba el cordial saludo de un lector “carente de amplitud y hondura intelectual “ , con muy reducido repertorio de palabrotas pero ferviente seguidor de su columna, desde antes que “el tamal de dulce” llegara a su vida como padre y a la nuestra como sus lectores.
Atentamente
Efrén Schwarz a(Chuarcito el niño héroe)
Friday, February 19, 2010
Cervical Mucus That Looks Like Snot
Two shorties ...
Carta abierta a Germán Dehesa y a José Ramón Fernández
Mis Queridos Chaparritos,
Agarro una bronca que pudiera not mine, but the courage to read what you wrote today in the newspaper Reforma me emotionally involved in this mess. The chaos in question are the answers given by Xavier Aguirre (which I seem to say the least "objective"), some questions in an interview.
I split, you say Don Herman, referring to the answers "... are totally stupid, uncalled for and without a hint of sensitivity or intellectual acuity. Declare warning so abysmal that one is stupid, "asks a lot of attributes for an answer that simply requires objectivity, in terms of" intellectual acuity "in some times you had, now, sadly, that child from 2 primary school, is limited to pitorreos to the "physics" of its victims, (the fat of Casterns and Gomez Mont, the resemblance of Beltrones with Capulina or Norberto Rivera with Fred Flintstone), do not ask much of a great coach (intellect, which is) when you like "writer" does not offer or do so only for a small sector of women who "admire", I know the reason this admiration and the certainty that there is, I mention it only because you do several times a week in his column by referring to them as their "cuatachas."
also says "... are millions of us still prefer "(as opposed to the fact that Xavier Aguirre and has so stated, prefer to live outside Mexico) as if this decision (live in Mexico) was good, the only or heroic, it makes me a bullshit to say the least that the only reason that a majority think the fact one way to think or act differently is wrong. And to finish
you say "... Xavier Aguirre who is my friend and I hope to remain so ..." when before he said "my" beloved "(sic) Xavier, you behaved like a beast quadraphonic (sic)" ... what is their concept of friendship Germain? , Friends, I think, may differ between them, but publicly attacking a friend like you did leave a very bad place to "friendship" would think of a "friend" who publicly told the same thing to you today wrote about "his friend." If no column theme, better not write more instead of shaping public differences with his "friends" and insult them so blatantly.
Now, about the column Joserra indescribable ... so you say no? You say "you had to say in Spain and have not had the courage to say in Mexico", this according to your sin is the only Xavier, and to agree to agree with all statements. If you said there was because there asked him, Xavier has never been known for cowardice, has always accepted its responsibilities in public, talk of cowardice is very sensitive especially when it comes from a journalist who has been characterized by means to hide behind and after their height (because you know nobody is going to hit a little guy to look like a coward) to systematically attack "absolutely everything." Continuing
".. you are not the right person or the most qualified to say whether Mexico is a country "screwed" or not ... "as you, who would be the" person ideal?, is there "the person"? .. Do not be stupid Joserra, no "person" for expressing a point of view.
wanted to mention a few points in your column to be objective about my differences, but I see that your entire column is a "waste of shit", no waste, if it is Mexicans who have been good poets, or because Nobel prizes and a good university, this means that in Mexico we are screwed. So
cunning and cowardly talk about his "failure" in Atletico Madrid, you're talking about the best Mexican coach, not me, I am not the "person", or what someone says in particular what says the place has served as "technical" teams around the world, its income (in the labor market, they are a road map for the evaluation of performance) and achievement. You say
English parents but proud of being Mexican, unmistakable symbol of nationalism asshole .... "The cheapest pride is national pride, which betrays the person who feels the lack of individual qualities of which he may be proud. Johann W. Goethe .- "I do not know if Goethe is the" ideal person "to talk about nationalism,
Greetings to the two
Carta abierta a Germán Dehesa y a José Ramón Fernández
Mis Queridos Chaparritos,
Agarro una bronca que pudiera not mine, but the courage to read what you wrote today in the newspaper Reforma me emotionally involved in this mess. The chaos in question are the answers given by Xavier Aguirre (which I seem to say the least "objective"), some questions in an interview.
I split, you say Don Herman, referring to the answers "... are totally stupid, uncalled for and without a hint of sensitivity or intellectual acuity. Declare warning so abysmal that one is stupid, "asks a lot of attributes for an answer that simply requires objectivity, in terms of" intellectual acuity "in some times you had, now, sadly, that child from 2 primary school, is limited to pitorreos to the "physics" of its victims, (the fat of Casterns and Gomez Mont, the resemblance of Beltrones with Capulina or Norberto Rivera with Fred Flintstone), do not ask much of a great coach (intellect, which is) when you like "writer" does not offer or do so only for a small sector of women who "admire", I know the reason this admiration and the certainty that there is, I mention it only because you do several times a week in his column by referring to them as their "cuatachas."
also says "... are millions of us still prefer "(as opposed to the fact that Xavier Aguirre and has so stated, prefer to live outside Mexico) as if this decision (live in Mexico) was good, the only or heroic, it makes me a bullshit to say the least that the only reason that a majority think the fact one way to think or act differently is wrong. And to finish
you say "... Xavier Aguirre who is my friend and I hope to remain so ..." when before he said "my" beloved "(sic) Xavier, you behaved like a beast quadraphonic (sic)" ... what is their concept of friendship Germain? , Friends, I think, may differ between them, but publicly attacking a friend like you did leave a very bad place to "friendship" would think of a "friend" who publicly told the same thing to you today wrote about "his friend." If no column theme, better not write more instead of shaping public differences with his "friends" and insult them so blatantly.
Now, about the column Joserra indescribable ... so you say no? You say "you had to say in Spain and have not had the courage to say in Mexico", this according to your sin is the only Xavier, and to agree to agree with all statements. If you said there was because there asked him, Xavier has never been known for cowardice, has always accepted its responsibilities in public, talk of cowardice is very sensitive especially when it comes from a journalist who has been characterized by means to hide behind and after their height (because you know nobody is going to hit a little guy to look like a coward) to systematically attack "absolutely everything." Continuing
".. you are not the right person or the most qualified to say whether Mexico is a country "screwed" or not ... "as you, who would be the" person ideal?, is there "the person"? .. Do not be stupid Joserra, no "person" for expressing a point of view.
wanted to mention a few points in your column to be objective about my differences, but I see that your entire column is a "waste of shit", no waste, if it is Mexicans who have been good poets, or because Nobel prizes and a good university, this means that in Mexico we are screwed. So
cunning and cowardly talk about his "failure" in Atletico Madrid, you're talking about the best Mexican coach, not me, I am not the "person", or what someone says in particular what says the place has served as "technical" teams around the world, its income (in the labor market, they are a road map for the evaluation of performance) and achievement. You say
English parents but proud of being Mexican, unmistakable symbol of nationalism asshole .... "The cheapest pride is national pride, which betrays the person who feels the lack of individual qualities of which he may be proud. Johann W. Goethe .- "I do not know if Goethe is the" ideal person "to talk about nationalism,
Greetings to the two
Subscribe to:
Comments (Atom)