Once input self-defined datasource table in topic's basic info, system will automatically generate a table named as “the name of the self-defined datasource table"_prop, which we called “prop table”. This table can be used to manage the status of self-defined datasource. Its structure is showed as below:
|
CREATE TABLE "the name of the self-defined datasource table"_prop (ID VARCHAR2(50) NOT NULL, TITLE VARCHAR2(1000) NOT NULL, SITEID VARCHAR2(10) NOT NULL, TOPIC VARCHAR2(10) NOT NULL, STATE NUMBER, CREATEDATE DATE DEFAULT SYSDATE NOT NULL, PUBLISHDATE DATE, CONSTRAINT PK_"the name of the self-defined datasource table"_prop PRIMARY KEY (ID,TOPIC) ); COMMENT ON COLUMN "the name of the self-defined datasource table"_prop.TITLE IS ''title'; COMMENT ON COLUMN "the name of the self-defined datasource table"_prop.SITEID IS 'site id'; COMMENT ON COLUMN "the name of the self-defined datasource table"_prop.TOPIC IS 'topic id'; COMMENT ON COLUMN "the name of the self-defined datasource table"_prop.STATE IS 'status'; COMMENT ON COLUMN "the name of the self-defined datasource table"_prop.CREATEDATE IS 'create date'; COMMENT ON COLUMN "the name of the self-defined datasource table"_prop.PUBLISHDATE IS 'publish date'; |
All categories of self-defined datasource must be derived from CustomArticle.
CustomArticle can realize self-defined datasource under default situation.
Below are its features:
1.Fields will be stored as TagRS format except “id”, “title”, “createdate”
and “publishdate”. TagRS is similar to “Hashtable”, which take datasource’s
capitalized field name as index.
2.Operations on attachment are unavailable. All operating values for attachment tag are null.
3.It provides default support for serial NpsEvent. All these events will
solely respond to events launched by current topic.
1)default response for InsertEvent: insert data into prop table which designated by topic. If Topic designates “publishing” as its default status, it should be published.
2)default response for UpdateEvent: update the “title” value which is in “prop” table. If the status of current article is “published” or “to publish”, it should be re-published.
3)default response for DeleteEvent: if the article is already published, all static pages, SOLR index and “prop” table record should be deleted.
4)default response for Ready2PublishEvent: publish the article, and automatically generate “PublishEvent” notice.
5)default response for PublishEvent: deliver to SOLR for fulltext index.
4.Not provide front-end management interface. If you need to manage self-defined datasource in NPS, you should re-develop it.
|
public Product(NpsContext inCtxt,Topic top,ResultSet rs) throws Exception { super(inCtxt,rs.getString("id"),rs.getString("title"),top); //load main information LoadMainInfo(rs,0); //load local information LoadLocalInfos(); //load picture LoadAttaches(); //load notified user LoadNotifyInfo(); } |
|
public boolean HasFiled(String fieldName) { if(fieldName==null || fieldName.length()==0) return false; String key = fieldName.trim(); if(key.length()==0) return false; key = key.toUpperCase(); if(key.equalsIgnoreCase("name")) return true; if(key.equalsIgnoreCase("code")) return true;//产品代码 if(key.equalsIgnoreCase("category")) return true; if(key.equalsIgnoreCase("origin")) return true; if(key.equalsIgnoreCase("producer")) return true; if(key.equalsIgnoreCase("exporter")) return true; if(key.equalsIgnoreCase("brand")) return true; if(key.equalsIgnoreCase("material")) return true; if(key.equalsIgnoreCase("product_size")) return true; if(key.equalsIgnoreCase("product_weight")) return true; if(key.equalsIgnoreCase("carton")) return true; if(key.equalsIgnoreCase("carton_weight")) return true; if(key.equalsIgnoreCase("purchase_price")) return true; if(key.equalsIgnoreCase("price")) return true; if(key.equalsIgnoreCase("fob")) return true; if(key.equalsIgnoreCase("package_quantity")) return true; if(key.equalsIgnoreCase("lead_time")) return true; if(key.equalsIgnoreCase("moq")) return true; if(key.equalsIgnoreCase("MinimumMoney")) return true; if(key.equalsIgnoreCase("product_spec")) return true; if(key.equalsIgnoreCase("package_spec")) return true; if(fields==null) return false; return fields.HasField(key); } public Object GetField(String fieldName) throws NpsException { if(fieldName==null || fieldName.length()==0) return null; String key = fieldName.trim(); if(key.length()==0) return null; key = key.toUpperCase(); if(key.equalsIgnoreCase("name")) return name; if(key.equalsIgnoreCase("code")) return code; if(key.equalsIgnoreCase("category")) return category; if(key.equalsIgnoreCase("origin")) return origin; if(key.equalsIgnoreCase("producer")) return producer; if(key.equalsIgnoreCase("exporter")) return exporter; if(key.equalsIgnoreCase("brand")) return brand; if(key.equalsIgnoreCase("material")) return material; if(key.equalsIgnoreCase("product_size")) return product_size; if(key.equalsIgnoreCase("product_weight")) return product_weight; if(key.equalsIgnoreCase("carton")) return carton; if(key.equalsIgnoreCase("carton_weight")) return carton_weight; if(key.equalsIgnoreCase("purchase_price")) return purchase_price;//进价 if(key.equalsIgnoreCase("price")) return purchase_price; if(key.equalsIgnoreCase("fob")) return fob; if(key.equalsIgnoreCase("package_quantity")) return package_quantity;//包装数量 if(key.equalsIgnoreCase("lead_time")) return lead_time; if(key.equalsIgnoreCase("moq")) return moq; if(key.equalsIgnoreCase("MinimumMoney")) return GetMinimumMoney(); if(key.equalsIgnoreCase("product_spec")) return product_spec; if(key.equalsIgnoreCase("package_spec")) return package_spec; if(fields==null) return null; return fields.GetField(key); } |
|
//publish the ready-to-publish information, prepare each topic public void Publish() throws NpsException { //Fire Event EventIssue.GetIssue().FireReady2PublishEvent(this,"FT_PRODUCT"); } |
|
//The topic is concerned on its own product public void Insert(Object observer, InsertEvent event) { if(observer instanceof Topic) { Topic t = (Topic)observer; if(!unit_id.equals(t.GetSite().GetUnit().GetId())) return; super.Insert(t,event); } } |
“Attach” class is the base class of all attachment class. “Article” class is responsible for managing “Attach” collection.
|
public String GetURL() { return PRODUCT_ATTACH_URL + Utils.FormateDate( art.GetCreateDate() , "yyyy/MM/dd") + "/" + id + (suffix==null?"":suffix); } public File GetOutputFile() { String temp_filepath = Utils.FormateDate(art.GetCreateDate(),"yyyy/MM/dd") +"/"; temp_filepath = temp_filepath.replaceAll("//","/"); if(temp_filepath.startsWith("/")) { temp_filepath = temp_filepath.substring(1); } File temp_file = new File( PRODUCT_ATTACH_PATH,temp_filepath); temp_file.mkdirs(); return new File(temp_file, id + (suffix==null?"":suffix)); } |
|
public Object clone() throws CloneNotSupportedException { return super.clone(); } |
After developing Java class, you should configure “custom.xml” to realize automatic load.
|
<?xml version="1.0" encoding="UTF-8"?> <root> #Each kind of self-defined datasource should be independently put under one “CustomArticle” node. There could be multiple “CustomArticle” ports under “root” node. <CustomArticle> #Each “CustomArticle” node must have one “table” and “class” node, otherwise, it will be neglected when loading. #“table” means the table name of self-defined datasource that need to be applied. It should be capitalized. #“class” means the re-developed self-defined datasource name that need to be loaded. We advise to use fully qualified class name. The class must be put under “common/lib”、“WEB-INF/classes” and “WEB-INF/lib”. <table>FT_PRODUCT</table> <class>nps.extra.trade.Product</class> # “property” node is not necessary unless for self-defined configuration. “property” can be globally shared. # the name of “property” lower-level node is “property” variable name. Its value is variable’s dereference. Note: the value is the result of “trim”. <property> <PRODUCT_ATTACH_PATH>c:\\web\\products\\</PRODUCT_ATTACH_PATH> <PRODUCT_ATTACH_URL>/products/</PRODUCT_ATTACH_URL> </property> </CustomArticle> #“event” node is not necessary unless for processing self-defined event. With regard to the “NpsEvent” processing method which is overloaded by “CustomArticle” derived class, it is not necessary to configure it; the system will automatically load it when the system gets started. #There can only be four kinds of node (“insert”、“update”、“delete”、“ready” and “publish”) that under “event”. They should respectively match along with the “InsertEvent”、“UpdateEvent”、 “DeleteEvent”、“Ready2PublishEvent”、“PublishEvent”. #“key” value is the same as the “KEY” value which publish event notice in self-defined datasource. #The “Product” example below can be applied to automatically send customers e-mail when products get published. <event> <publish key="FT_PRODUCT">nps.extra.trade.ProductManager</publish> </event> </root> |