com.networknt.light.rule.product.AbstractProductRule.java Source code

Java tutorial

Introduction

Here is the source code for com.networknt.light.rule.product.AbstractProductRule.java

Source

/*
 * Copyright 2015 Network New Technologies Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.networknt.light.rule.product;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
import com.networknt.light.rule.AbstractRule;
import com.networknt.light.rule.Rule;
import com.networknt.light.server.DbService;
import com.networknt.light.util.ServiceLocator;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.index.OCompositeKey;
import com.orientechnologies.orient.core.index.OIndex;
import com.orientechnologies.orient.core.metadata.schema.OSchema;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.serialization.serializer.OJSONWriter;
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Created by husteve on 10/14/2014.
 */
public abstract class AbstractProductRule extends AbstractRule implements Rule {
    ObjectMapper mapper = ServiceLocator.getInstance().getMapper();

    public abstract boolean execute(Object... objects) throws Exception;

    protected ODocument getProductByHostName(String host, String name) {
        ODocument product = null;
        ODatabaseDocumentTx db = ServiceLocator.getInstance().getDb();
        try {
            OIndex<?> hostNameIdx = db.getMetadata().getIndexManager().getIndex("hostNameIdx");
            // this is a unique index, so it retrieves a OIdentifiable
            OCompositeKey key = new OCompositeKey(host, name);
            OIdentifiable oid = (OIdentifiable) hostNameIdx.get(key);
            if (oid != null) {
                product = (ODocument) oid.getRecord();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            db.close();
        }
        return product;
    }

    protected ODocument addProduct(Map<String, Object> data, String userId) throws Exception {
        ODocument product = null;
        ODatabaseDocumentTx db = ServiceLocator.getInstance().getDb();
        Map<String, Object> productMap = (Map<String, Object>) ServiceLocator.getInstance()
                .getMemoryImage("productMap");
        ConcurrentMap<Object, Object> cache = (ConcurrentMap<Object, Object>) productMap.get("cache");
        if (cache == null) {
            cache = new ConcurrentLinkedHashMap.Builder<Object, Object>().maximumWeightedCapacity(1000).build();
            productMap.put("cache", cache);
        }

        OSchema schema = db.getMetadata().getSchema();
        try {
            db.begin();
            product = new ODocument(schema.getClass("Product"));
            product.field("host", data.get("host"));
            product.field("name", data.get("name"));
            product.field("attributes", data.get("attributes"));
            java.util.Date d = new java.util.Date();
            product.field("createDate", d);
            product.field("updateDate", d);
            product.field("createUser", userId);
            product.save();
            cache.put(product.field("@rid").toString(), product);
            String categoryRid = (String) data.get("categoryRid");
            if (categoryRid != null) {
                // get the category and update entities list
                ODocument category = getCategoryByRid(categoryRid);
                List entities = category.field("entities");
                if (entities == null) {
                    entities = new ArrayList();
                }
                entities.add(product);
                category.field("entities", entities);
                category.save();
            }
            db.commit();
        } catch (Exception e) {
            db.rollback();
            e.printStackTrace();
            throw e;
        } finally {
            db.close();
        }
        return product;
    }

    protected void delProduct(String productRid) throws Exception {
        ODocument product = DbService.delODocumentByRid(productRid);
        // rebuild cache in memory.
        Map<String, Object> productMap = (Map<String, Object>) ServiceLocator.getInstance()
                .getMemoryImage("productMap");
        // update central cache
        ConcurrentMap<Object, Object> cache = (ConcurrentMap<Object, Object>) productMap.get("cache");
        if (cache != null) {
            cache.remove(productRid);
        }
    }

    protected void updProduct(String productRid, Map<String, Object> data) throws Exception {
        ODocument product = getProductByRid(productRid);
        if (product != null) {
            product.field("name", data.get("name"));
            product.field("attributes", data.get("attributes"));
            product.field("updateDate", new java.util.Date());
            product.save();
        }
    }

    protected List<ODocument> searchProductDb(Map<String, Object> criteria) {
        List<ODocument> products = null;
        StringBuilder sql = new StringBuilder("SELECT FROM Product ");
        String whereClause = DbService.getWhereClause(criteria);
        if (whereClause != null && whereClause.length() > 0) {
            sql.append(whereClause);
        }

        String sortedBy = (String) criteria.get("sortedBy");
        String sortDir = (String) criteria.get("sortDir");
        if (sortedBy != null) {
            sql.append(" ORDER BY ").append(sortedBy);
            if (sortDir != null) {
                sql.append(" ").append(sortDir);
            }
        }
        Integer pageSize = (Integer) criteria.get("pageSize");
        Integer pageNo = (Integer) criteria.get("pageNo");
        if (pageNo != null && pageSize != null) {
            sql.append(" SKIP ").append((pageNo - 1) * pageSize);
            sql.append(" LIMIT ").append(pageSize);
        }
        System.out.println("sql=" + sql);
        ODatabaseDocumentTx db = ServiceLocator.getInstance().getDb();
        try {
            OSQLSynchQuery<ODocument> query = new OSQLSynchQuery<ODocument>(sql.toString());
            products = db.command(query).execute();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            db.close();
        }
        return products;
    }

    protected String searchProduct(Map<String, Object> criteria) throws Exception {
        // first check if the full list is in cache.
        String json = null;
        Map<String, Object> result = new HashMap<String, Object>();
        List<ODocument> products = new ArrayList<ODocument>();
        int total = 0;
        String host = (String) criteria.get("host");
        Map<String, Object> productMap = (Map<String, Object>) ServiceLocator.getInstance()
                .getMemoryImage("productMap");
        Map<String, Object> hostMap = (Map<String, Object>) productMap.get(host);
        if (hostMap == null) {
            hostMap = new ConcurrentHashMap<String, Object>(10, 0.9f, 1);
            productMap.put(host, hostMap);
        }
        String key = null;
        String categoryRid = (String) criteria.get("categoryRid");
        if (categoryRid != null) {
            key = categoryRid + criteria.get("sortedBy");
        } else {
            key = "" + criteria.get("sortedBy");
        }
        Integer pageNo = (Integer) criteria.remove("pageNo");
        Integer pageSize = (Integer) criteria.remove("pageSize");
        List<String> list = (List<String>) hostMap.get(key);
        if (list == null) {
            // not in cache, search from db and put them in cache.
            List<ODocument> docs = searchProductDb(criteria);
            total = docs.size();
            int i = 0;
            list = new ArrayList<String>();
            for (ODocument doc : docs) {
                list.add(doc.field("@rid").toString());
                if (i >= pageSize * (pageNo - 1) && i < pageSize * pageNo) {
                    products.add(doc);
                    i++;
                    // put only the current page in cache.
                    ConcurrentMap<Object, Object> cache = (ConcurrentMap<Object, Object>) productMap.get("cache");
                    if (cache == null) {
                        cache = new ConcurrentLinkedHashMap.Builder<Object, Object>().maximumWeightedCapacity(1000)
                                .build();
                        productMap.put("cache", cache);
                    }
                    cache.put(doc.field("@rid").toString(), doc);
                }
            }
        } else {
            // we have a list of rids.
            total = list.size();
            for (int i = pageSize * (pageNo - 1); i < Math.min(pageSize * pageNo, list.size()); i++) {
                String rid = (String) list.get(i);
                ConcurrentMap<Object, Object> cache = (ConcurrentMap<Object, Object>) productMap.get("cache");
                ODocument product = (ODocument) cache.get(rid);
                if (product == null) {
                    // not in cache, get from db and put it into the cache.
                    product = DbService.getODocumentByRid(rid);
                    cache.put(rid, product);
                }
                products.add(product);
            }
        }
        if (products != null && products.size() > 0) {
            result.put("total", total);
            result.put("products", OJSONWriter.listToJSON(products, null));
            json = mapper.writeValueAsString(result);
        }
        return json;
    }

    protected Map<String, Object> refreshCache(String host) {
        Map<String, Object> productMap = (Map<String, Object>) ServiceLocator.getInstance()
                .getMemoryImage("productMap");
        Map<String, Object> criteria = new HashMap<String, Object>();
        criteria.put("host", host);
        criteria.put("sortedBy", "updateDate");
        criteria.put("sortDir", "DESC");
        List<ODocument> products = searchProductDb(criteria);
        Map<String, Object> hostMap = new ConcurrentHashMap<String, Object>(2, 0.9f, 1);
        List<String> newList = new ArrayList<String>();
        ConcurrentMap<Object, Object> cache = (ConcurrentMap<Object, Object>) productMap.get("cache");
        if (cache == null) {
            cache = new ConcurrentLinkedHashMap.Builder<Object, Object>().maximumWeightedCapacity(1000).build();
            productMap.put("cache", cache);
        }
        int i = 0;
        int pageSize = 2; // TODO get from config
        for (ODocument product : products) {
            // cache the first page for now. most people will read the first page as it contains
            // new posts.
            if (i < pageSize) {
                cache.put(product.field("@rid").toString(), product);
            }
            newList.add(product.field("@rid").toString());
        }
        hostMap.put("newList", newList);

        // TODO build hot list

        productMap.put(host, hostMap);
        return hostMap;
    }
}