`
lan861698789
  • 浏览: 3962 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论
收藏列表
标题 标签 来源
请假
时间
原因
天数
休假
2014-11-16
V3 前台和后台联调
1
y
2014-11-17 6:00 - 23:00
V3 前台和后台联调
1 or 0.5
y
2014-12-13

1
Y
2015-03-22
Production support 早晨5点到了,下午4点走 ,karl
1
2014.0415休假一天
2015-04-06
清明节加班(当时加班两天,一天是3倍工资,另一天调休)
1
5.5日用完了,老婆病了


4.5日清明节,加班,三倍

5.1日劳动节,加班,三倍
SQL
--seesion
SELECT * FROM CP_SE_SESSION  WHERE SESS_DATE IS NOT NULL ORDER BY SESS_DATE DESC
SELECT * FROM  cp_pt_cust_demo WHERE customer_no IN ( SELECT cust_no FROM cp_se_entity WHERE  rel_no NOT IN ( SELECT cust_reln_no FROM cp_cu_risk_profile ) )and  custtype='002';
select * from cp_se_entity where cust_no = '175295' and rel_no not in ( SELECT    cust_reln_no    FROM      cp_cu_risk_profile)

/******************************************************************************************************************/
/*******************************                 MM                     *******************************************/
/******************************************************************************************************************/
--加载cache
SELECT * FROM CP_MM_LABEL_MASTER  WHERE SCRN_ID='MM' AND LABEL_TYPE='O' AND CONTROL = '88:GCG' -- MEMFIS_LANGAUGE_88:GCG
SELECT * from CP_MM_CODED_VALUE A,  CP_MM_LANG_PHRASES B 
WHERE A.CONTROL = B.CONTROL AND A.CDE_DESP_LBL_ID = B.LBL_ID AND B.LANG_ID = 'en' AND A.CONTROL = '88:GCG' ORDER BY A.CONTROL, A.CDE_IDX, A.SEQ_NO
--MEMFIS_CV_READBY_88:GCG or MEMFIS_CV_READFROM_88:GCG

-- lable list 
SELECT * FROM CP_MM_LABEL_MASTER where tag_id = 'SCREEN_REF'; --<view:literal parm="SCREEN_REF"  />
SELECT * FROM CP_MM_LABEL_MASTER where CONTROL = '88:GCG' and LANG_ID = 'en';
select * from CP_MM_LABEL_MASTER_P;

SELECT * FROM cp_mm_label_master_P;
SELECT * FROM cp_mm_label_master_H;



-- module list 
select * from CP_MM_MODULES where MOD_DESC_LBL_ID = '97174';
select * from CP_MM_LANG_PHRASES where LBL_ID = '97174';
select * from CP_MM_MODULES A,CP_MM_LANG_PHRASES B WHERE A.CONTROL= B.CONTROL AND A.MOD_DESC_LBL_ID= B.LBL_ID;

--下拉框
--:<dropdown:html codeIndex="MM_STATUS" codeValue="<%=objSearchLabelDom.getAuthStatus()%>" />
--cache:MEMFIS_CV_READFROM_88:GCG
select * from cp_mm_coded_value where cde_idx='MM_STATUS';
select * from cp_Mm_lang_phrases where lbl_id=1465;

SELECT * FROM CP_MM_CODED_VALUE A,  CP_MM_LANG_PHRASES B 
WHERE A.CONTROL = B.CONTROL AND A.CDE_DESP_LBL_ID = B.LBL_ID AND B.LANG_ID = 'en' AND A.CONTROL = '88:GCG' 
ORDER BY A.CONTROL, A.CDE_IDX, A.SEQ_NO;


/**
* <view:literal parm="MAINTAIN_LABEL" />
*/
SELECT * FROM CP_MM_LABEL_MASTER  WHERE SCRN_ID='MM' AND LABEL_TYPE='O' AND CONTROL = '88:GCG' and tag_id = 'MAINTAIN_LABEL'


/*************************************
*  currency
**************************************/
select * from cp_mm_currency  where ccy_code='138'
select * from cp_mm_currency_h  where ccy_code='138'
select * from cp_mm_currency_p  where ccy_code='138'
UPDATE cp_mm_currency_p SET MAKER_ID='HC01265' where ccy_code='138'
select * from cp_mm_lang_phrases where lbl_id=157810 
select * from cp_mm_lang_phrases_h where lbl_id=157810
select * from cp_mm_lang_phrases_p where lbl_id=157810


/*************************************
*  profile
**************************************/
select * from cp_se_risk_profile where cust_reln_no ='1075767' ORDER BY SESS_DATE DESC  --find the history  ??,????sessionId
select * From cp_se_profile_response where fk_sess_id= 2007373

SELECT * FROM cp_cu_risk_profile INNER JOIN cp_se_session sess	ON prof.fk_sess_id = sess.sess_id and prof.control = sess.control	
  left JOIN cp_se_entity entity	ON sess.ent_id = entity.ent_id AND sess.control = entity.control -- status = A 
      
SELECT * FROM cp_se_risk_profile -- status != A

/*************************************
*  question and response
**************************************/
select *
  From ((select ques_id, ques_type, lbl_id, lbl_txt, seq_no 
           From cp_mm_questions A
           left join cp_mm_lang_phrases B on ques_lbl_id = lbl_id
          where A.cust_type = 'IND'
            --and module_id = 'P000'
            and lang_id = 'en'
          order by ques_id asc) ques  left  join
        (select fk_ques_id as ques_id, resp_id, lbl_id, lbl_txt , seq_no 
           from cp_mm_responses
           left join cp_mm_lang_phrases on long_resp_lbl_id = lbl_id and cust_type = 'IND'
                                       where lang_id = 'en' order by ques_id asc) response on
        ques.ques_id = response.ques_id)  order by ques.ques_id, response.resp_id  asc;
        
--cp_mm_questions.ques_id = cp_mm_responses.fk_ques_id
select * from cp_mm_questions,cp_mm_lang_phrases where  cust_type = 'IND' and ques_id = '2' and ques_lbl_id = lbl_id and lang_id = 'en' and ques_type = '20';
select * from cp_mm_responses where fk_ques_id = '2' and cust_type = 'IND';

select * from sp.cp_mm_coded_value where cde_idx = 'MM_QUESTION_INDICATOR' and control = '88:GCG';
/*************************************
* profile get document 
**************************************/
SELECT doc.document_ref_id	as imageId	FROM CP_SE_DOCUMENTS doc WHERE  doc.document_type = 'PROFILE_REPORT' AND status = 'A' and doc.fk_sess_id = #value#
SELECT doc.DOCUMENT as document FROM CP_SE_DOCUMENTS doc WHERE	doc.document_type = 'PROFILE_REPORT'	and status = 'U' and doc.fk_sess_id = #fkSessId#

SELECT CDE_VAL 	FROM cp_mm_coded_value WHERE cde_idx = 'BASE_CCY'; --CNY
SELECT CDE_VAL 	FROM cp_mm_coded_value WHERE cde_idx = 'OperatingLevel'; --R
/*************************************
* profilecheck
**************************************/
select * from cp_se_risk_profile where fk_sess_id = '118480' ;
SELECT * FROM CP_SE_DOCUMENTS doc  WHERE  	doc.fk_sess_id = '118480'   	and  doc.document_type = 'PROFILE_REPORT'   	and status = 'U'
update CP_SE_DOCUMENTS doc set status = 'U'  WHERE  	doc.fk_sess_id = '118448'   	and  doc.document_type = 'PROFILE_REPORT'   	and status = 'A'

/******************************************************************************************************************/
/*******************************                 goal                     *******************************************/
/******************************************************************************************************************/
--education
select * from sp_hk.cp_mm_coded_value where cde_idx = 'FP_RET_EDU_COUNTRY'; --AU
select * from sp_hk.cp_mm_coded_value where cde_idx = 'FP_EDU_SCHOOL_TYPE';
select * from sp_hk.cp_mm_coded_value where cde_idx = 'FP_EDU_COST';
select * from sp_hk.cp_mm_coded_value where cde_idx = 'FP_LIV_COST';
select * from sp_hk.cp_mm_coded_value where cde_idx = 'FP_EDU_YEARS'; --UKUNI
select * from sp.cp_mm_coded_value where cde_idx = 'FP_EDU_EXPECT_AGE';
select * from sp.cp_mm_coded_value where cde_idx = 'FP_PER_TO_FUND';
select * from sp.cp_mm_coded_value where cde_idx = 'FP_EDU_INFLATION';
select * from sp.cp_mm_coded_value where cde_idx = 'FP_LIV_INFLATION';

--retilment
select * from sp.cp_mm_coded_value where cde_idx = 'FP_RET_EDU_COUNTRY';
select * from sp.cp_mm_coded_value where cde_idx = 'FP_RET_NEEDS_AMOUNT';
select * from sp.cp_mm_coded_value where cde_idx = 'FP_RET_INFLATION_RATE';
select * from sp.cp_mm_coded_value where cde_idx = 'FP_AST_GROWTH_RATE_AF_RET';
select * from sp.cp_mm_coded_value where cde_idx = 'FP_AVG_LIFE';
select * from sp.cp_mm_coded_value where cde_idx = 'FP_RET_AGE';

select * from sp_hk.cp_cu_fp_goal;
select * from sp_hk.CP_FP_TXN_JOURNAL;

--tibco log
select * from sp_hk.sptibcolog 

/******************************************************************************************************************/
/*******************************                 insurance                     *******************************************/
/******************************************************************************************************************/
select * from 
CP_SE_INS_NEEDS;
CP_SE_DEPENDANTS;
CP_SE_INS_POLICY;
CP_MM_QUESTIONS;
CP_SE_PROFILE_RESPONSE;
CP_SE_INS_LAPSE;
cp_se_ins_fna;
select * from sp.CP_SE_INSU_REC_TXN_INFO
select * from sp.CP_SE_INS_NET_ASSETS where cust_reln_no = '000486886'
CP_SE_INS_LIABILITIES;
select SESSION_ID,TXN_NO,SECURITY_TYPE,RECOMMENDATION_CATE from sp.CP_SE_INSU_REC_TXN_INFO where SESSION_ID =?
---PROCESS
CP_INS_BASE_PKG:
CP_PRC_GET_INS_NEEDS
CP_PRC_GET_INS_RECOMMEND
CP_PRC_GET_INS_SUMMARY
CP_SET_SUMMARY_PROF
FUND_FINDER_INSURANCE
--question type
--question type = 110,首页的qustion
--question type = 130,点击recommadation disclosures按钮

--code value
  select * from sp.cp_mm_coded_value where cde_idx = 'INS_SECURITY_TYPE' and control = '88:GCG'; --HLTH,PA,TERM,UNIV,WLIF:整个生活,健康保险,人身意外伤害,万能寿险 --也就是 product SECURITY_TYPE
  select * from sp.CP_MM_PRODUCT where SECURITY_TYPE = 'HLTH'; -- search product.
  select * from sp.cp_mm_lang_phrases where lbl_id in (select cde_desp_lbl_id from sp.cp_mm_coded_value where cde_idx = 'INS_SECURITY_TYPE') and control = '88:GCG' and lang_id = 'en';
  
-- recommdation 首页显示的, 是根据前面age question 问题 的回答来显示的
--code value :INS_LIFESTAGE ,配置了 RECOMMENDATION_CATE_TYPE 和 age reponse 的 mapping:  1-HLTH, 表示 如果 问题是1,则显示 HLTH到页面。
select * from sp.cp_mm_questions where question_indicator = 'I' and ques_type = '110';
select * from sp.CP_MM_LANG_PHRASES where lbl_id = '87803710';
select * from SP.cp_mm_responses where fk_ques_id = '200';
SELECT *  FROM SP.cp_mm_coded_value  WHERE cde_idx ='INS_LIFESTAGE' and SUBSTR(cde_key,1,1) = 'age question''s reponse seq_no';
  select * from sp.cp_mm_coded_value where cde_idx = 'INS_LIFESTAGE'; -- age question.
  select * from sp.cp_mm_coded_value where cde_idx = 'INS_LIFE_STAGE';
  select * from sp.cp_mm_lang_phrases where lbl_id in (select cde_desp_lbl_id from sp.cp_mm_coded_value where cde_idx = 'INS_LIFE_STAGE');
--  recommdation 首页显示 的 type 对应什么 product catetory
select * from sp.cp_mm_coded_value where cde_idx = 'RECOMMENDATION_CATE_TYPE'; --recommendation首页面显示的类型
select * from sp.cp_mm_lang_phrases where lbl_id in (select cde_desp_lbl_id from sp.cp_mm_coded_value where cde_idx = 'RECOMMENDATION_CATE_TYPE');
select * from sp.cp_mm_coded_value where cde_idx like '%_TO_SUB_CATE_MAP'; --存放 的是 INS_SECURITY_TYPE 和 recommendation category 的对应关系
select * from sp.cp_mm_lang_phrases where lbl_id in (select cde_desp_lbl_id from sp.cp_mm_coded_value where cde_idx like '%_TO_SUB_CATE_MAP');
select * from sp.cp_mm_coded_value where cde_idx like 'CEP_TO_SUB_CATE_MAP';
select * from sp.cp_mm_lang_phrases where lbl_id in (select cde_desp_lbl_id from sp.cp_mm_coded_value where cde_idx like 'CEP_TO_SUB_CATE_MAP');

select * from sp.cp_mm_coded_value where cde_idx like 'INS_POL_FREQ';
select * from sp.cp_mm_lang_phrases where lbl_id in (select cde_desp_lbl_id from sp.cp_mm_coded_value where cde_idx like 'INS_POL_FREQ');
select * from sp.cp_mm_coded_value where cde_idx like 'L3_SECURITY_TYPE';
select * from sp.cp_mm_lang_phrases where lbl_id in (select cde_desp_lbl_id from sp.cp_mm_coded_value where cde_idx like 'L3_SECURITY_TYPE');
select * from sp.cp_mm_coded_value where cde_idx like 'INS_TXN_TYPE';
select * from sp.cp_mm_lang_phrases where lbl_id in (select cde_desp_lbl_id from sp.cp_mm_coded_value where cde_idx like 'INS_TXN_TYPE');
select * from sp.cp_mm_coded_value where cde_idx like 'CODE_INDEX_SUIT_TYPE';
select * from sp.cp_mm_lang_phrases where lbl_id in (select cde_desp_lbl_id from sp.cp_mm_coded_value where cde_idx like 'SuitabilityTypeList');

--final soluthion page
select * from sp.cp_mm_coded_value where cde_idx = 'INS_NET_ASSETS' -- asset
select * from sp.cp_mm_coded_value where cde_idx = 'INS_LIABILITIES' -- liabilities

--get history order
select * from SP.CP_SE_PRE_ORDER  where module_id = 'S100' and fk_sess_id = '?'
select SESSION_ID,TXN_NO,SECURITY_TYPE,RECOMMENDATION_CATE from CP_SE_INSU_REC_TXN_INFO where SESSION_ID =?
select * from sp.cp_se_pre_order where fk_sess_id = '3649167'; -- parent_transaction_no 对应父类的transaction_no

--L3 check
SELECT * FROM SP.CP_MM_CODED_VALUE WHERE CDE_IDX = 'L3_SECURITY_TYPE' AND CONTROL = '88:GCG';
select * from sp.cp_mm_coded_value where cde_idx = 'INS_SECURITY_TYPE' AND CONTROL = '88:GCG' AND CDE_VAL IN (SELECT CDE_VAL FROM SP.CP_MM_CODED_VALUE WHERE CDE_IDX = 'L3_SECURITY_TYPE' AND CONTROL = '88:GCG');
select ILP_PROD_CODE AS 外层, product_code as L3 from  cp_mm_ilp_funds; --L3 will search from here

/*************************************************************************************************************************************************************
*  FX RATE
**************************************************************************************************************************************************************/
-- 1 RMB = 1.2497 HKD
-- 国家是HKD,现在的currency是RMB,怎么换算?
-- MONEY(lcy,hkd) / MID_RATE = RMB
select * from sp.cp_mm_currency where ccy_code in (344,156);
select * from sp.cp_mm_currency where ccy_code_alpha in ('CNY','USD') 
select * from sp.cp_mm_fx_rate where base_ccy_code = '344' and ccy_code = '156'

/*************************************************************************************************************************************************************
*  product portfiol
**************************************************************************************************************************************************************/
 select * from CP_MM_PRODUCT_PORTFOLIO_P;
 select * from cp_mm_prod_port_allocation_p where prod_port_id = 'lancePre';
 
 /*************************************************************************************************************************************************************
*  fulfillment
**************************************************************************************************************************************************************/
 select s.INVESTMENT_ACCOUNT_NO,s.CASH_ACCOUNT_NO,s.* from cp_se_order s order by session_id desc;  -- INVESTMENT_ACCOUNT_NO to INV_ACCT_NO
 select d.INV_ACCT_NO, d.* from CP_SE_PRE_ORDER d order by fk_sess_id desc;

  /*************************************************************************************************************************************************************
*  upload image
Document_Ref_ID = imageId(from document)
**************************************************************************************************************************************************************/
 delete from cp_se_documents where FK_Sess_ID='45665' and Document_Type='PASSPORT_REPORT'
 select * from cp_se_documents where FK_Sess_ID='45665' and Document_Type='PASSPORT_REPORT'
 
pdf 签名
public static void mergeSignatureForField(PdfStamper stamper, String nodeName, Image sign) throws DocumentException {
		AcroFields form = stamper.getAcroFields();
		float[] signature = form.getFieldPositions(nodeName);
		System.out.println("nodeName="+nodeName+" signature="+signature);
		if (signature != null && signature.length == 5) {
			int page = (int) signature[0];
			Rectangle rect = new Rectangle(signature[1], signature[2], signature[3], signature[4]);
			sign.scaleToFit(rect.getWidth(), rect.getHeight());
			sign.setAbsolutePosition(signature[1] + (rect.getWidth() - sign.getScaledWidth()) / 2, signature[2] + (rect.getHeight() - sign.getScaledHeight()) / 2);
			PdfContentByte under = stamper.getOverContent(page);
			under.addImage(sign);
		}
	}
2014-03-05-01
<xml-any-element java-attribute="body" xml-path="nitf:body/nitf:body.content/nitf:block" dom-handler="com.endplay.feeds.jobs.domhandler.SAXOBodyDomHandler" />

2014-02-21 15:02:04
http://www.hjenglish.com/level/lingjichu/ 英标
http://www.wooyun.org/bugs/wooyun-2014-050305 乌云
2013-05-07 19:44:58
<?xml version="1.0"?>
<!DOCTYPE project>

<project name="build-common-plugin" xmlns:antelope="antlib:ise.antelope.tasks">
	<import file="build-common.xml" />

	<path id="xmltask.classpath">
		<fileset dir="${project.dir}/../build-files/lib" includes="*.jar" />
	</path>

	<taskdef 
		name="xmltask" 
		classpathref="xmltask.classpath"
		classname="com.oopsconsultancy.xmltask.ant.XmlTask"/>
	
	<if>
		<available file="docroot/WEB-INF/liferay-plugin-package.properties" />
		<then>
			<property file="docroot/WEB-INF/liferay-plugin-package.properties" prefix="plugin-package" />
			<property name="plugin.jars" value="${plugin-package.portal-dependency-jars}" />
			<property name="plugin.tlds" value="${plugin-package.portal-dependency-tlds}" />
			<property name="plugin.latest.version" value="${plugin-package.module-incremental-version}" />
		</then>
		<else>
			<property name="plugin.latest.version" value="1" />
		</else>
	</if>

	<tstamp>
    	<format property="build_tstamp" pattern="yyyyMMdd.hhmm" />
    </tstamp>
   	<property name="env.BUILD_NUMBER" value="${env.DEPLOYENV}.${build_tstamp}" />

	<property name="plugin.version" value="${env.BUILD_NUMBER}" />
	
	<antelope:stringutil string="${basedir}" property="plugin.name.beginindex">
		<antelope:lastindexof string="${file.separator}" />
	</antelope:stringutil>

	<antelope:math
		datatype="int"
		operand1="${plugin.name.beginindex}"
		operand2="1"
		operation="+"
		result="plugin.name.beginindex"
	/>

	<antelope:stringutil string="${basedir}" property="plugin.name">
		<antelope:substring beginindex="${plugin.name.beginindex}" />
	</antelope:stringutil>

	<property name="plugin.latest.file" value="dist/latest/${plugin.name}-${lp.version}.${plugin.latest.version}.war" />
	<property name="plugin.local.file" value="dist/${plugin.version}/${plugin.name}-${lp.version}.${plugin.version}.war" />
	<property name="plugin.file" value="${plugin.local.file}" />

	<target name="all">
		<antcall target="clean" />
		<antcall target="deploy" />
	</target>

	<target name="build-client">
		<property name="client.url" value="http://localhost:8080/${plugin.name}/axis" />

		<echo message="Make sure the server is listening on ${client.url}." />
		<echo message="" />

		<mkdir dir="docroot/WEB-INF/client/src" />

		<java
			classname="com.liferay.portal.tools.PortalClientBuilder"
			classpathref="portal.classpath"
			failonerror="true"
			fork="true"
			newenvironment="true"
		>
			<jvmarg value="-Dexternal-properties=com/liferay/portal/tools/dependencies/portal-tools.properties" />
			<arg value="docroot/WEB-INF/server-config.wsdd" />
			<arg value="docroot/WEB-INF/client/src" />
			<arg value="docroot/WEB-INF/client/namespace-mapping.properties" />
			<arg value="${client.url}" />
		</java>

		<mkdir dir="docroot/WEB-INF/client/classes" />

		<antcall target="compile-java">
			<param name="javac.classpathref" value="portal.classpath" />
			<param name="javac.destdir" value="docroot/WEB-INF/client/classes" />
			<param name="javac.srcdir" value="docroot/WEB-INF/client/src" />
		</antcall>

		<zip destfile="docroot/WEB-INF/client/${plugin.name}-client.jar">
			<fileset dir="docroot/WEB-INF/client/classes" />
			<fileset dir="docroot/WEB-INF/client/src" />
		</zip>

		<delete dir="docroot/WEB-INF/client/classes" />
		<delete dir="docroot/WEB-INF/client/src" />
	</target>

	<target name="build-db">
		<java
			classname="com.liferay.portal.tools.DBBuilder"
			classpathref="portal.classpath"
			fork="true"
			maxmemory="384m"
			newenvironment="true"
		>
			<arg value="-Dexternal-properties=com/liferay/portal/tools/dependencies/portal-tools.properties" />
			<arg value="db.database.name=${database.name}" />
			<arg value="db.database.types=${database.types}" />
			<arg value="db.sql.dir=docroot/WEB-INF/sql" />
		</java>

		<delete file="velocity.log" quiet="true" />
	</target>

	<target name="build-lang">
		<antcall target="build-lang-cmd">
			<param name="lang.dir" value="docroot/WEB-INF/src/content" />
			<param name="lang.file" value="Language" />
			<param name="lang.translate" value="true" />
		</antcall>
	</target>

	<target name="build-lang-cmd">
		<java
			classname="com.liferay.portal.tools.LangBuilder"
			classpathref="portal.classpath"
			fork="true"
			newenvironment="true"
		>
			<jvmarg value="-Dexternal-properties=com/liferay/portal/tools/dependencies/portal-tools.properties" />
			<jvmarg value="-Dfile.encoding=UTF-8" />
			<jvmarg value="-Duser.country=US" />
			<jvmarg value="-Duser.language=en" />
			<arg value="lang.dir=${lang.dir}" />
			<arg value="lang.file=${lang.file}" />
			<arg value="lang.plugin=true" />
			<arg value="lang.translate=${lang.translate}" />
		</java>

		<copy file="${lang.dir}/${lang.file}.properties" tofile="${lang.dir}/${lang.file}_en.properties" />
	</target>

	<target name="build-service">
		<if>
			<not>
				<isset property="service.input.file" />
			</not>
		    	<then>
		    		<property name="service.input.file" value="${basedir}/docroot/WEB-INF/service.xml" />
			</then>
		</if>
		
		<if>
			<available file="${service.input.file}" />
			<then>
				<antcall target="package-plugin-dependencies" />
				<antcall target="compile-common-dependencies" />
				<antcall target="jar-plugin-common"/>
				
				<mkdir dir="docroot/WEB-INF/classes" />
				<mkdir dir="docroot/WEB-INF/lib" />
				<mkdir dir="docroot/WEB-INF/service" />
				<mkdir dir="docroot/WEB-INF/sql" />
				<mkdir dir="docroot/WEB-INF/src" />

				<copy todir="docroot/WEB-INF/classes">
					<fileset dir="docroot/WEB-INF/src" excludes="**/*.java" />
				</copy>

				<!-- Don't forget the jars specified in the liferay=plugin-package.properties file -->
				<copy todir="docroot/WEB-INF/lib">
					<fileset dir="${app.server.lib.portal.dir}" includes="${plugin.jars}" />
				</copy>

				<path id="service.classpath">
					<path refid="lib.classpath" />
					<path refid="portal.classpath" />
					<fileset dir="${app.server.lib.portal.dir}" includes="commons-digester.jar,commons-lang.jar,easyconf.jar" />
					<fileset dir="docroot/WEB-INF/lib" includes="*.jar" />
					<pathelement location="docroot/WEB-INF/classes" />
				</path>


				<java
					classname="com.liferay.portal.tools.servicebuilder.ServiceBuilder"
					classpathref="service.classpath"
					outputproperty="service.test.output"
				>
					<arg value="-Dexternal-properties=com/liferay/portal/tools/dependencies/portal-tools.properties" />
					<arg value="-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger" />
					<arg value="service.input.file=${service.input.file}" />
					<arg value="service.hbm.file=${basedir}/docroot/WEB-INF/src/META-INF/portlet-hbm.xml" />
					<arg value="service.orm.file=${basedir}/docroot/WEB-INF/src/META-INF/portlet-orm.xml" />
					<arg value="service.model.hints.file=${basedir}/docroot/WEB-INF/src/META-INF/portlet-model-hints.xml" />
					<arg value="service.spring.file=${basedir}/docroot/WEB-INF/src/META-INF/portlet-spring.xml" />
					<arg value="service.spring.base.file=${basedir}/docroot/WEB-INF/src/META-INF/base-spring.xml" />
					<arg value="service.spring.cluster.file=${basedir}/docroot/WEB-INF/src/META-INF/cluster-spring.xml" />
					<arg value="service.spring.dynamic.data.source.file=${basedir}/docroot/WEB-INF/src/META-INF/dynamic-data-source-spring.xml" />
					<arg value="service.spring.hibernate.file=${basedir}/docroot/WEB-INF/src/META-INF/hibernate-spring.xml" />
					<arg value="service.spring.infrastructure.file=${basedir}/docroot/WEB-INF/src/META-INF/infrastructure-spring.xml" />
					<arg value="service.spring.shard.data.source.file=${basedir}/docroot/WEB-INF/src/META-INF/shard-data-source-spring.xml" />
					<arg value="service.api.dir=${basedir}/docroot/WEB-INF/service" />
					<arg value="service.impl.dir=${basedir}/docroot/WEB-INF/src" />
					<arg value="service.json.file=${basedir}/docroot/js/service.js" />
					<arg value="service.sql.dir=${basedir}/docroot/WEB-INF/sql" />
					<arg value="service.sql.file=tables.sql" />
					<arg value="service.sql.indexes.file=indexes.sql" />
					<arg value="service.sql.indexes.properties.file=indexes.properties" />
					<arg value="service.sql.sequences.file=sequences.sql" />
					<arg value="service.auto.namespace.tables=true" />
					<arg value="service.bean.locator.util=com.liferay.util.bean.PortletBeanLocatorUtil" />
					<arg value="service.props.util=com.liferay.util.service.ServiceProps" />
					<arg value="service.plugin.name=${plugin.name}" />
				</java>

				<echo>${service.test.output}</echo>

				<if>
					<contains string="${service.test.output}" substring="Error" />
					<then>
						<fail>Service Builder generated exceptions.</fail>
					</then>
				</if>

				<delete file="ServiceBuilder.temp" />

				<mkdir dir="docroot/WEB-INF/service-classes" />

				<!--<delete file="docroot/WEB-INF/lib/${plugin.name}-service.jar" />-->
				<delete file="${project.dir}/lib/${plugin.name}-service.jar" />

				<path id="service.classpath">
					<fileset dir="${project.dir}/lib" includes="*.jar" />
					<fileset dir="${app.server.lib.global.dir}" includes="*.jar" />
					<fileset dir="docroot/WEB-INF/lib" excludes="${plugin.name}-service.jar" includes="*.jar" />
				</path>

				<antcall target="compile-java">
					<param name="javac.classpathref" value="service.classpath" />
					<param name="javac.destdir" value="docroot/WEB-INF/service-classes" />
					<param name="javac.srcdir" value="docroot/WEB-INF/service" />
					<reference refid="service.classpath" torefid="service.classpath" />
				</antcall>

				<zip
					basedir="docroot/WEB-INF/service-classes"
					destfile="docroot/WEB-INF/service-classes/${plugin.name}-service.jar"
				/>

				<!--
				     If this project contained a xustom-jsp directive, the following would
				     create a service jar and place it into the WEB-INF/lib directory under 
				     the custom-jsp directory.  That would ensure that the service jar would
				     get copied into the ROOT's WEB-INF/lib.  However, the hot deploy hook that
				     we added lets us determine if we want the ROOT to have a copy of the service
				     jar and during deployment, the hot deploy listener will move it to the 
				     ROOT's library only if desired.
				  -->
				<!--
				<if>
					<available file="docroot/WEB-INF/liferay-hook.xml" />
					<then>
						<echo message="read property from liferay-hook.xml"/>
						<xmltask source="docroot/WEB-INF/liferay-hook.xml">
							<copy path="//hook/custom-jsp-dir/text()" property="destDir" />
						</xmltask>
					</then>
				</if>
				<if>
					<isset property="destDir" />
					<then>
						<mkdir dir="docroot${destDir}/WEB-INF/lib" />
						<copy todir="docroot${destDir}/WEB-INF/lib">
							<fileset dir="docroot/WEB-INF/lib/" includes="${plugin.name}-service.jar" />
						</copy>
					</then>
				</if>
				-->
				
		        <!--<copy todir="${project.dir}/lib">
					<fileset dir="docroot/WEB-INF/lib/" includes="${plugin.name}-service.jar" />
				</copy>-->
				<copy todir="${project.dir}/lib" overwrite="true">
					<fileset dir="docroot/WEB-INF/service-classes/" includes="${plugin.name}-service.jar" />
				</copy>

				<delete dir="docroot/WEB-INF/service-classes" />
				
				<antcall target="copy-service-to-dist" />
			</then>
		</if>
	</target>
	
	<target name="copy-service-to-dist">
		<if>
			<not>
				<isset property="service.input.file" />
			</not>
		    	<then>
		    		<property name="service.input.file" value="${basedir}/docroot/WEB-INF/service.xml" />
			</then>
		</if>
		
		<if>
			<available file="${service.input.file}" />
			<then>
				<mkdir dir="dist/latest/service" />
				<mkdir dir="dist/latest/sql" />
				
				<if>
					<equals arg1="${create.dist.dev}" arg2="true" />
					<then>
						<mkdir dir="dist/${plugin.version}/service" />
						<mkdir dir="dist/${plugin.version}/sql" />
					
				        <copy todir="dist/${plugin.version}/sql">
							<fileset dir="docroot/WEB-INF/sql/" />
						</copy>
						
						<copy todir="dist/${plugin.version}/service">
							<fileset dir="${project.dir}/lib/" includes="${plugin.name}-service.jar" />
						</copy>
					</then>
				</if>

				<!--<copy todir="dist/latest/service">
					<fileset dir="docroot/WEB-INF/lib/" includes="${plugin.name}-service.jar" />
				</copy>-->
				<copy todir="dist/latest/service">
					<fileset dir="${project.dir}/lib/" includes="${plugin.name}-service.jar" />
				</copy>

				<!--<copy todir="dist/${plugin.version}/service">
					<fileset dir="docroot/WEB-INF/lib/" includes="${plugin.name}-service.jar" />
				</copy>-->

		        <copy todir="dist/latest/sql">
					<fileset dir="docroot/WEB-INF/sql/" />
				</copy>
			</then>
		</if>
	</target>

	<target name="copy-common-to-dist">
		<if>
			<available file="docroot/WEB-INF/common/src" />
			<then>
				<mkdir dir="dist/latest/common" />
				
				<copy todir="dist/latest/common">
					<fileset dir="${project.dir}/lib/" includes="ep-common-${plugin.name}*.jar" />
				</copy>
				
				<if>
					<equals arg1="${create.dist.dev}" arg2="true" />
					<then>
						<mkdir dir="dist/${plugin.version}/common" />
						
						<copy todir="dist/${plugin.version}/common">
							<fileset dir="${project.dir}/lib/" includes="ep-common-${plugin.name}*.jar" />
						</copy>
					</then>
				</if>

				<!--<copy todir="dist/latest/common">
					<fileset dir="docroot/WEB-INF/lib/" includes="ep-common-${plugin.name}*.jar" />
				</copy>

		        <copy todir="dist/${plugin.version}/common">
					<fileset dir="docroot/WEB-INF/lib/" includes="ep-common-${plugin.name}*.jar" />
				</copy>-->

				
				<if>
					<available file="docroot/WEB-INF/endplay-properties.xml" />
					<then>
						<xmltask source="docroot/WEB-INF/endplay-properties.xml">
							<copy path="//endplay/common/dependent-jars/text()" trim="true" property="dependent-jars" />
						</xmltask>
						
						<if>
							<isset property="dependent-jars" />
							<then>
								<copy todir="dist/latest/common" verbose="true">
									<fileset dir="${app.server.lib.portal.dir}" includes="${required.portal.jars}" />
									<fileset dir="${app.server.lib.portal.dir}" includes="${dependent-jars}" />
									<fileset dir="docroot/WEB-INF/lib" includes="${dependent-jars}" />
								</copy>
								
								<if>
									<equals arg1="${create.dist.dev}" arg2="true" />
									<then>
										<copy todir="dist/${plugin.version}/common" verbose="true">
											<fileset dir="${app.server.lib.portal.dir}" includes="${required.portal.jars}" />
											<fileset dir="${app.server.lib.portal.dir}" includes="${dependent-jars}" />
											<fileset dir="docroot/WEB-INF/lib" includes="${dependent-jars}" />
										</copy>
									</then>
								</if>

								<copy todir="${project.dir}/lib" verbose="true">
									<fileset dir="${app.server.lib.portal.dir}" includes="${required.portal.jars}" />
									<fileset dir="${app.server.lib.portal.dir}" includes="${dependent-jars}" />
									<fileset dir="docroot/WEB-INF/lib" includes="${dependent-jars}" />
								</copy>
							</then>
						</if>
					</then>
				</if>
			</then>
		</if>
	</target>
	
	<target name="copy-src-to-dist">
		<mkdir dir="dist/latest/src" />

		<copy todir="dist/latest/src">
			<fileset dir="${project.dir}/lib/" includes="ep-common-${plugin.name}*.jar" />
		</copy>
		
		<if>
			<equals arg1="${create.dist.dev}" arg2="true" />
			<then>
				<mkdir dir="dist/${plugin.version}/src" />
				
		        <copy todir="dist/${plugin.version}/common">
					<fileset dir="${project.dir}/lib/" includes="ep-common-${plugin.name}*.jar" />
				</copy>
			</then>
		</if>
	</target>

	<target name="build-wsdd" depends="compile">
		<path id="wsdd.classpath">
			<path refid="lib.classpath" />
			<path refid="portal.classpath" />
			<fileset dir="docroot/WEB-INF/lib" includes="*.jar" />
			<pathelement location="docroot/WEB-INF/classes" />
		</path>

		<java
			classname="com.liferay.portal.tools.WSDDBuilder"
			classpathref="wsdd.classpath"
			fork="true"
			maxmemory="256m"
			newenvironment="true"
		>
			<jvmarg value="-Dexternal-properties=com/liferay/portal/tools/dependencies/portal-tools.properties" />
			<jvmarg value="-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger" />
			<arg value="wsdd.input.file=docroot/WEB-INF/service.xml" />
			<arg value="wsdd.server.config.file=docroot/WEB-INF/server-config.wsdd" />
			<arg value="wsdd.service.namespace=Plugin" />
			<arg value="wsdd.output.path=docroot/WEB-INF/src/" />
		</java>
	</target>

	<target name="clean" description="clean">
		<delete dir="docroot/WEB-INF/classes" />
		<delete dir="docroot/WEB-INF/ext/classes" />
		<delete dir="docroot/WEB-INF/common/classes" />
		<delete dir="test-classes" />
		<delete dir="test-results" />
		<delete dir="tmp" />
		<delete file="${plugin.file}" />
		<delete file="${plugin.local.file}" />

		<delete includeemptydirs="true">
			<fileset dir="docroot" includes="**/.sass-cache/**" />
			<fileset dir="docroot" includes="**/.sprite.png" />
			<fileset dir="docroot" includes="**/.sprite.properties" />
			<fileset dir="docroot" includes="**/Thumbs.db" />
		</delete>

		<antcall target="clean-portal-dependencies" />
	</target>

	<target name="clean-portal-dependencies">
		<if>
			<available file="docroot/WEB-INF/lib" />
			<then>
				<delete>
					<fileset dir="docroot/WEB-INF/lib" includes="${required.portal.jars}" />
					<fileset dir="docroot/WEB-INF/lib" includes="${plugin.jars}" />
				</delete>
			</then>
		</if>

		<if>
			<available file="docroot/WEB-INF/tld" />
			<then>
				<delete>
					<fileset dir="docroot/WEB-INF/tld" includes="${plugin.tlds}" />
				</delete>
			</then>
		</if>

		<if>
			<available file="tmp/WEB-INF/lib" />
			<then>
				<delete>
					<fileset dir="tmp/WEB-INF/lib" includes="${required.portal.jars}" />
					<fileset dir="tmp/WEB-INF/lib" includes="${plugin.jars}" />
				</delete>
			</then>
		</if>

		<if>
			<available file="tmp/WEB-INF/tld" />
			<then>
				<delete>
					<fileset dir="tmp/WEB-INF/tld" includes="${plugin.tlds}" />
				</delete>
			</then>
		</if>
		<!-- added by w. berks -->
		<if>
			<available file="docroot/WEB-INF/ext" />
			<then>
				<delete dir="docroot/WEB-INF/ext/classes" />
			</then>
		</if>
	</target>
	
	<target name="clean-all" depends="clean">
		<antcall target="undeploy" />
	</target>
	
	<!-- added by cim -->
	<target name="clean-all-jars" depends="clean-all">
		<if>
			<available file="docroot/WEB-INF/common" />
			<then>
				<delete>
					<fileset dir="docroot/WEB-INF/lib/" includes="**/ep-common-${plugin.name}.jar" />
					<fileset dir="${app.server.lib.global.dir}" includes="**/ep-common-${plugin.name}*.jar" />
					<fileset dir="${app.server.lib.portal.dir}" includes="**/ep-common-${plugin.name}.jar" />
				</delete>
			</then>
		</if>
		<if>
			<available file="docroot/WEB-INF/common/lib" />
			<then>
				<delete>
					<fileset dir="docroot/WEB-INF/common/lib" includes="**/ep-common-${plugin.name}.jar" />
				</delete>
			</then>
		</if>
		<if>
			<available file="dist/latest/common" />
			<then>
				<delete>
					<fileset dir="dist/latest/common/" includes="**/*.jar" />
				</delete>
			</then>
		</if>
		<if>
			<available file="docroot/WEB-INF/ext" />
			<then>
				<delete>
					<fileset dir="docroot/WEB-INF/lib/" includes="**/ext-${plugin.name}*.jar" />
					<fileset dir="${app.server.lib.portal.dir}" includes="**/ext-${plugin.name}*.jar" />
				</delete>
			</then>
		</if>
		<if>
			<available file="docroot/WEB-INF/custom/WEB-INF/lib" />
			<then>
				<delete>
					<fileset dir="docroot/WEB-INF/custom/WEB-INF/lib/" includes="**/ext-${plugin.name}*.jar" />
				</delete>
			</then>
		</if>
		<if>
			<available file="docroot/WEB-INF/service" />
			<then>
				<delete>
					<fileset dir="docroot/WEB-INF/lib/" includes="**/${plugin.name}-service.jar" />
					<fileset dir="${app.server.lib.global.dir}" includes="**/${plugin.name}-service.jar" />
					<fileset dir="${app.server.lib.portal.dir}" includes="**/${plugin.name}-service.jar" />
				</delete>
			</then>
		</if>
		<if>
			<available file="dist/latest/src" />
			<then>
				<delete>
					<fileset dir="dist/latest/src/" includes="**/*.jar" />
				</delete>
			</then>
		</if>
		<if>
			<available file="${project.dir}/lib" />
			<then>
				<delete>
					<fileset dir="${project.dir}/lib/" includes="**/ep-common-${plugin.name}*.jar" />
					<fileset dir="${project.dir}/lib/" includes="**/${plugin.name}-service.jar" />
					<fileset dir="${project.dir}/lib/" includes="**/ext-${plugin.name}*.jar" />
				</delete>
			</then>
		</if>
		<delete file="${plugin.latest.file}" />
	</target>
	
	<target name="clean-dev" depends="clean">
		<if>
			<available file="dist" />
			<then>
				<delete includeemptydirs="true">
					<fileset dir="dist" includes="**/dev**/**" />
				</delete>
			</then>
		</if>
	</target>

	<target name="clean-deploy" depends="clean-all, deploy">
	</target>

	<target name="compile">
		<echo message="compiling ${plugin.name}"/>
		
		<antcall target="merge" />

		<mkdir dir="docroot/WEB-INF/classes" />
		<mkdir dir="docroot/WEB-INF/lib" />
		
		<if>
			<isset property="disable.tmp-compile.dir" />
			<then><!-- do nothing --></then>
			<else>
				<antcall target="create-compile-tmp-dir"/>
			</else>
		</if>
			

		<antcall target="package-plugin-dependencies" />
		<antcall target="compile-common-dependencies" />
		
		<if>
			<available file="dist/latest/service" type="dir" />
			<then>
				<copy todir="${project.dir}/lib" overwrite="true">
					<fileset dir="dist/latest/service/" includes="${plugin.name}-service.jar" />
				</copy>
			</then>
		</if>
		
		<!-- Added by w. berks
		     Lets us create a jar for hook plugins.  This
		     jar can contain additional classes that do not
		     extend existing Liferay actions.
		  -->
		<if>
			<available file="docroot/WEB-INF/common/src" type="dir" />
			<then>
				<!--<antcall target="compile-plugin-common" />-->
				<antcall target="jar-plugin-common"/>
			</then>
		</if>
		<if>
			<available file="docroot/WEB-INF/ext/src" type="dir" />
			<then>
				<antcall target="compile-plugin-ext" />
				<antcall target="jar-plugin-ext"/>
			</then>
		</if>

		<copy todir="docroot/WEB-INF/lib">
			<fileset dir="${app.server.lib.portal.dir}" includes="${plugin.jars}" />
		</copy>

		<copy todir="docroot/WEB-INF/tld">
			<fileset dir="${app.server.portal.dir}/WEB-INF/tld" includes="${plugin.tlds}" />
		</copy>

		<if>
			<available file="docroot/WEB-INF/src" />
			<then>
				<if>
					<available file="tmp" />
					<then>
						<path id="plugin-lib.classpath">
							<fileset dir="docroot/WEB-INF/lib" includes="*.jar" />
							<fileset dir="tmp/WEB-INF/lib" includes="*.jar" />
							<pathelement location="docroot/WEB-INF/classes" />
							<pathelement location="tmp/WEB-INF/classes" />
						</path>
					</then>
					<else>
						<path id="plugin-lib.classpath">
							<fileset dir="docroot/WEB-INF/lib" includes="*.jar" />
							<pathelement location="docroot/WEB-INF/classes" />
						</path>
					</else>
				</if>

				<copy todir="docroot/WEB-INF/lib">
					<fileset dir="${app.server.lib.portal.dir}" includes="${required.portal.jars}" />
				</copy>

				<if>
					<available file="docroot/WEB-INF/lib/portal-impl.jar" />
					<then>
						<fail>
.

Detected inclusion of portal-impl.jar in WEB-INF/lib.

portal-impl.jar is designed with a large number of singleton classes which are
instantiated on the basis that they will exist alone in the application server.

While compile time issues may be resolved, portlets cannot be made to work by
simply adding portal-impl.jar, because doing so violates the above assumption,
and the resulting problems will be extremely difficult to debug.

Please find a solution that does not require portal-impl.jar.
						</fail>
					</then>
				</if>
				
				<antcall target="compile-java">
					<param name="javac.classpathref" value="plugin.classpath" />
					<param name="javac.destdir" value="docroot/WEB-INF/classes" />
					<param name="javac.srcdir" value="docroot/WEB-INF/src" />
					<reference refid="plugin-lib.classpath" torefid="plugin-lib.classpath" />
				</antcall>
			</then>
		</if>

		<antcall target="merge" />
		
		<if>
			<available file="${project.dir}/tmp-compile" type="dir"/>
			<then>
				<mkdir dir="${project.dir}/tmp-compile/${plugin.name}" />
			</then>
		</if>
		
		<if>
			<isset property="disable.tmp-compile.dir" />
			<then><!-- do nothing --></then>
			<else>
				<antcall target="delete-compile-tmp-dir"/>
			</else>
		</if>
		
		<antcall target="clean-portal-dependencies" />
	</target>
	
	<target name="compile-plugin-ext">
		<if>
			<available file="docroot/WEB-INF/ext/src" type="dir" />
			<then>
				<mkdir dir="docroot/WEB-INF/ext/classes" />
				<antcall target="compile-java">
					<param name="javac.classpathref" value="plugin-ext.classpath" />	
					<param name="javac.destdir" value="docroot/WEB-INF/ext/classes" />
					<param name="javac.srcdir" value="docroot/WEB-INF/ext/src" />
				</antcall>
			</then>
		</if>
	</target>

	<target name="compile-plugin-common">
		<if>
			<available file="docroot/WEB-INF/common/src" type="dir" />
			<then>
				<if>
					<available file="docroot/WEB-INF/endplay-properties.xml" />
					<then>
						<mkdir dir="docroot/WEB-INF/common/classes" />
						<mkdir dir="docroot/WEB-INF/common/lib" />
						<xmltask source="docroot/WEB-INF/endplay-properties.xml">
							<copy path="//endplay/common/dependent-jars/text()" trim="true" property="dependent-jars" />
						</xmltask>
						
						<if>
							<isset property="dependent-jars" />
							<then>
								<copy todir="docroot/WEB-INF/common/lib" verbose="true">
									<fileset dir="${app.server.lib.portal.dir}" includes="${required.portal.jars}" />
									<fileset dir="${app.server.lib.portal.dir}" includes="${dependent-jars}" />
									<fileset dir="docroot/WEB-INF/lib" includes="${dependent-jars}" />
								</copy>
							</then>
						</if>
						
						<antcall target="compile-java">
							<param name="javac.classpathref" value="plugin-common.classpath" />
							<param name="javac.destdir" value="docroot/WEB-INF/common/classes" />
							<param name="javac.srcdir" value="docroot/WEB-INF/common/src" />
						</antcall>
						<delete>
							<fileset dir="docroot/WEB-INF/common/lib" />
						</delete>
					</then>
					<else>
						<fail>
Please set up the endplay-properties.xml file before compiling the common library.
						</fail>
					</else>
				</if>
			</then>
		</if>
	</target>

	<target name="compile-test">
		<mkdir dir="test-classes" />
		<mkdir dir="test-results" />

		<copy todir="test-classes">
			<fileset dir="test" includes="**/*.png,**/*.properties,**/*.xml" />
		</copy>

		<if>
			<available file="tmp" />
			<then>
				<path id="plugin-lib.classpath">
					<fileset dir="docroot/WEB-INF/lib" includes="*.jar" />
					<fileset dir="tmp/WEB-INF/lib" includes="*.jar" />
					<pathelement location="docroot/WEB-INF/classes" />
					<pathelement location="tmp/WEB-INF/classes" />
				</path>
			</then>
			<else>
				<path id="plugin-lib.classpath">
					<fileset dir="docroot/WEB-INF/lib" includes="*.jar" />
					<pathelement location="docroot/WEB-INF/classes" />
				</path>
			</else>
		</if>

		<antcall target="compile-java">
			<param name="javac.classpathref" value="test.classpath" />
			<param name="javac.destdir" value="test-classes" />
			<param name="javac.srcdir" value="test" />
			<reference refid="plugin-lib.classpath" torefid="plugin-lib.classpath" />
		</antcall>
	</target>
	
	<target name="package-plugin-dependencies">
		<if>
			<isset property="plugin-package.required-deployment-contexts" />
			<then>
				<for list="${plugin-package.required-deployment-contexts}" param="required.deployment.context">
					<sequential>
						<if>
							<available file="${project.dir}/hooks/@{required.deployment.context}/dist/latest/service/@{required.deployment.context}-service.jar" />
							<then>
								<copy
									file="${project.dir}/hooks/@{required.deployment.context}/dist/latest/service/@{required.deployment.context}-service.jar"
									todir="${project.dir}/lib"
									overwrite="true"
								/>
							</then>
							<elseif>
								<available file="${project.dir}/portlets/@{required.deployment.context}/dist/latest/service/@{required.deployment.context}-service.jar" />
								<then>
									<copy
										file="${project.dir}/portlets/@{required.deployment.context}/dist/latest/service/@{required.deployment.context}-service.jar"
										todir="${project.dir}/lib"
										overwrite="true"
									/>
								</then>
							</elseif>
							<elseif>
								<available file="${project.dir}/webs/@{required.deployment.context}/dist/latest/service/@{required.deployment.context}-service.jar" />
								<then>
									<copy
										file="${project.dir}/webs/@{required.deployment.context}/dist/latest/service/@{required.deployment.context}-service.jar"
										todir="${project.dir}/lib"
										overwrite="true"
									/>
								</then>
							</elseif>
						</if>
					</sequential>
				</for>
			</then>
		</if>
	</target>
	
	<target name="compile-common-dependencies">
		<if>
			<available file="docroot/WEB-INF/endplay-properties.xml" />
			<then>
				<xmltask source="docroot/WEB-INF/endplay-properties.xml">
					<copy path="//endplay/dependencies/commons/text()" trim="true" property="dependent.common.plugins" />
				</xmltask>
				
				<if>
					<isset property="dependent.common.plugins" />
					<then>
						<for list="${dependent.common.plugins}" param="required.common.plugin">
							<sequential>
								<if>
									<available file="${project.dir}/tmp-compile/@{required.common.plugin}" type="dir"/>
									<then>
										<!-- do nothing since already compiled by another plugin -->
										<echo message="@{required.common.plugin} already compiled by another plugin so skipping"/>
									</then>
									<elseif>
										<available file="${project.dir}/hooks/@{required.common.plugin}" />
										<then>
											<ant dir="${project.dir}/hooks/@{required.common.plugin}" target="compile" inheritAll="false">
												<property name="disable.tmp-compile.dir" value="true"/>
											</ant>
										</then>
									</elseif>
									<elseif>
										<available file="${project.dir}/portlets/@{required.common.plugin}" />
										<then>
											<ant dir="${project.dir}/portlets/@{required.common.plugin}" target="compile" inheritAll="false">
												<property name="disable.tmp-compile.dir" value="true"/>
											</ant>
										</then>
									</elseif>
									<elseif>
										<available file="${project.dir}/webs/@{required.common.plugin}" />
										<then>
											<ant dir="${project.dir}/webs/@{required.common.plugin}" target="compile" inheritAll="false">
												<property name="disable.tmp-compile.dir" value="true"/>
											</ant>
										</then>
									</elseif>
								</if>
							</sequential>
						</for>
					</then>
				</if>
			</then>
		</if>
	</target>

	<target name="deploy" depends="war">
		<copy file="${plugin.latest.file}" todir="${auto.deploy.dir}" />
		<antcall target="deploy-plugin-service" />
		<antcall target="deploy-plugin-common" />
		<antcall target="deploy-plugin-ext" />
	</target>
	
	<target name="deploy-all" depends="deploy,deploy-plugin-service,deploy-plugin-common,deploy-plugin-ext,deploy-plugin-dependencies,deploy-common-dependencies">
	</target>
	
	<target name="deploy-plugin-service">
		<property name="plugin-service.file" value="${plugin.name}-service.jar" />
		<if>
			<available file="dist/latest/service/${plugin-service.file}" />
			<then>
				<copy todir="${app.server.lib.global.dir}" verbose="true">
					<fileset dir="dist/latest/service" includes="${plugin-service.file}" />
				</copy>
				
				<if>
					<available file="docroot/WEB-INF/endplay-properties.xml" />
					<then>
						<xmltask source="docroot/WEB-INF/endplay-properties.xml">
							<copy path="//endplay/public-interface/@deploy-root-lib" trim="true" property="is-deploy-root-lib" />
						</xmltask>
						
						<if>
							<equals arg1="${is-deploy-root-lib}" arg2="true" />
							<then>
								<copy todir="${app.server.lib.portal.dir}" verbose="true">
									<fileset dir="dist/latest/service" includes="${plugin-service.file}" />
								</copy>
							</then>
						</if>

						<xmltask source="docroot/WEB-INF/endplay-properties.xml">
							<copy path="//endplay/public-interface/dependent-jars/text()" trim="true" property="dependent-jars" />
						</xmltask>
						
						<if>
							<isset property="dependent-jars" />
							<then>
								<copy todir="${app.server.lib.global.dir}" verbose="true">
									<fileset dir="${app.server.lib.portal.dir}" includes="${required.portal.jars}" />
									<fileset dir="${app.server.lib.portal.dir}" includes="${dependent-jars}" />
									<fileset dir="docroot/WEB-INF/lib" includes="${dependent-jars}" />
								</copy>
								<if>
									<equals arg1="${is-deploy-root-lib}" arg2="true" />
									<then>
										<copy todir="${app.server.lib.portal.dir}" verbose="true">
											<fileset dir="${app.server.lib.portal.dir}" includes="${required.portal.jars}" />
											<fileset dir="${app.server.lib.portal.dir}" includes="${dependent-jars}" />
											<fileset dir="docroot/WEB-INF/lib" includes="${dependent-jars}" />
											<fileset dir="${project.dir}/lib" includes="${dependent-jars}" />
										</copy>
									</then>
								</if>
							</then>
						</if>
					</then>
				</if>
			</then>
		</if>
	</target>
	
	<target name="deploy-plugin-common" depends="jar-plugin-common">
		<property name="plugin-common.file" value="ep-common-${plugin.name}.jar" />
		<if>
			<available file="dist/latest/common/${plugin-common.file}" />
			<then>
				<copy todir="${app.server.lib.global.dir}" verbose="true">
					<fileset dir="${project.dir}/lib" includes="${plugin-common.file}" />
				</copy>
				
				<if>
					<available file="docroot/WEB-INF/endplay-properties.xml" />
					<then>
						<xmltask source="docroot/WEB-INF/endplay-properties.xml">
							<copy path="//endplay/common/@deploy-root-lib" trim="true" property="is-deploy-root-lib" />
						</xmltask>
						
						<if>
							<equals arg1="${is-deploy-root-lib}" arg2="true" />
							<then>
								<copy todir="${app.server.lib.portal.dir}" verbose="true">
									<fileset dir="${project.dir}/lib" includes="${plugin-common.file}" />
								</copy>
							</then>
						</if>

						<xmltask source="docroot/WEB-INF/endplay-properties.xml">
							<copy path="//endplay/common/dependent-jars/text()" trim="true" property="dependent-jars" />
						</xmltask>
						
						<if>
							<isset property="dependent-jars" />
							<then>
								<copy todir="${app.server.lib.global.dir}" verbose="true">
									<fileset dir="${app.server.lib.portal.dir}" includes="${required.portal.jars}" />
									<fileset dir="${app.server.lib.portal.dir}" includes="${dependent-jars}" />
									<fileset dir="docroot/WEB-INF/lib" includes="${dependent-jars}" />
								</copy>
								<if>
									<equals arg1="${is-deploy-root-lib}" arg2="true" />
									<then>
										<copy todir="${app.server.lib.portal.dir}" verbose="true">
											<fileset dir="${app.server.lib.portal.dir}" includes="${required.portal.jars}" />
											<fileset dir="${app.server.lib.portal.dir}" includes="${dependent-jars}" />
											<fileset dir="docroot/WEB-INF/lib" includes="${dependent-jars}" />
										</copy>
									</then>
								</if>
							</then>
						</if>
					</then>
				</if>
			</then>
		</if>
	</target>
	
	<target name="deploy-plugin-ext">
		<property name="plugin-ext.file" value="ext-${plugin.name}-${lp.version}.jar" />
		<if>
			<available file="docroot/WEB-INF/liferay-hook.xml" />
			<then>
				<echo message="read property from liferay-hook.xml"/>
				<xmltask source="docroot/WEB-INF/liferay-hook.xml">
					<xmlcatalog refid="dtds"/>
					<copy path="//hook/custom-jsp-dir/text()" property="destDir" />
				</xmltask>
			</then>
			<else>
				<property name="destDir" value="/custom" />
			</else>
		</if>
		<if>
			<available file="docroot${destDir}/WEB-INF/lib/${plugin-ext.file}" />
			<then>
				<copy todir="${app.server.lib.portal.dir}" verbose="true">
					<fileset dir="docroot${destDir}/WEB-INF/lib" includes="${plugin-ext.file}" />
				</copy>
			</then>
		</if>
		<if>
			<available file="docroot${destDir}/WEB-INF/struts-config-ext.xml" />
			<then>
				<copy todir="${app.server.portal.dir}/WEB-INF" verbose="true" overwrite="true">
					<fileset dir="docroot${destDir}/WEB-INF" includes="struts-config-ext.xml" />
				</copy>
			</then>
		</if>
		<if>
			<available file="docroot${destDir}/WEB-INF/portlet-ext.xml" />
			<then>
				<copy todir="${app.server.portal.dir}/WEB-INF" verbose="true" overwrite="true">
					<fileset dir="docroot${destDir}/WEB-INF" includes="portlet-ext.xml" />
				</copy>
			</then>
		</if>
		<if>
			<available file="docroot${destDir}/WEB-INF/liferay-portlet-ext.xml" />
			<then>
				<copy todir="${app.server.portal.dir}/WEB-INF" verbose="true" overwrite="true">
					<fileset dir="docroot${destDir}/WEB-INF" includes="liferay-portlet-ext.xml" />
				</copy>
			</then>
		</if>
		<if>
			<available file="docroot${destDir}/WEB-INF/tiles-defs-ext.xml" />
			<then>
				<copy todir="${app.server.portal.dir}/WEB-INF" verbose="true" overwrite="true">
					<fileset dir="docroot${destDir}/WEB-INF" includes="tiles-defs-ext.xml" />
				</copy>
			</then>
		</if>
	</target>
	
	<target name="deploy-plugin-dependencies">
		<if>
			<isset property="plugin-package.required-deployment-contexts" />
			<then>
				<for list="${plugin-package.required-deployment-contexts}" param="required.deployment.context">
					<sequential>
						<if>
							<available file="${project.dir}/hooks/@{required.deployment.context}/dist/latest/service/@{required.deployment.context}-service.jar" />
							<then>
								<ant dir="${project.dir}/hooks/@{required.deployment.context}" target="deploy-plugin-service" inheritAll="false" />
							</then>
							<elseif>
								<available file="${project.dir}/portlets/@{required.deployment.context}/dist/latest/service/@{required.deployment.context}-service.jar" />
								<then>
									<ant dir="${project.dir}/portlets/@{required.deployment.context}" target="deploy-plugin-service" inheritAll="false" />
								</then>
							</elseif>
							<elseif>
								<available file="${project.dir}/webs/@{required.deployment.context}/dist/latest/service/@{required.deployment.context}-service.jar" />
								<then>
									<ant dir="${project.dir}/webs/@{required.deployment.context}" target="deploy-plugin-service" inheritAll="false" />
								</then>
							</elseif>
						</if>
					</sequential>
				</for>
			</then>
		</if>
	</target>
	
	<target name="deploy-common-dependencies">
		<if>
			<available file="docroot/WEB-INF/endplay-properties.xml" />
			<then>
				<xmltask source="docroot/WEB-INF/endplay-properties.xml">
					<copy path="//endplay/dependencies/commons/text()" trim="true" property="dependent.common.plugins" />
				</xmltask>
				
				<if>
					<isset property="dependent.common.plugins" />
					<then>
						<for list="${dependent.common.plugins}" param="required.common.plugin">
							<sequential>
								<if>
									<available file="${project.dir}/hooks/@{required.common.plugin}" />
									<then>
										<ant dir="${project.dir}/hooks/@{required.common.plugin}" target="deploy-plugin-common" inheritAll="false" />
									</then>
									<elseif>
										<available file="${project.dir}/portlets/@{required.common.plugin}" />
										<then>
											<ant dir="${project.dir}/portlets/@{required.common.plugin}" target="deploy-plugin-common" inheritAll="false" />
										</then>
									</elseif>
									<elseif>
										<available file="${project.dir}/webs/@{required.common.plugin}" />
										<then>
											<ant dir="${project.dir}/webs/@{required.common.plugin}" target="deploy-plugin-common" inheritAll="false" />
										</then>
									</elseif>
								</if>
							</sequential>
						</for>
					</then>
				</if>
			</then>
		</if>
	</target>

	<target name="check-liferay-deploy">
		<pathconvert property="foundDeploy" setonempty="false" pathsep=" ">
			<path>
				<fileset dir="${auto.deploy.dir}" includes="${plugin.name}*" />
			</path>
		</pathconvert>
	</target>
	
	<target name="direct-deploy" depends="war">
		<if>
			<antelope:endswith string="${plugin.name}" with="-ext" />
			<then>
				<java
					classname="com.liferay.portal.tools.deploy.ExtDeployer"
					classpathref="portal.classpath"
					fork="true"
					newenvironment="true"
				>

					<!-- Required Arguments -->

					<jvmarg value="-Dexternal-properties=com/liferay/portal/tools/dependencies/portal-tools.properties" />
					<jvmarg value="-Dliferay.lib.portal.dir=${app.server.lib.portal.dir}" />
					<jvmarg value="-Ddeployer.base.dir=./dist/latest" />
					<jvmarg value="-Ddeployer.dest.dir=${app.server.deploy.dir}" />
					<jvmarg value="-Ddeployer.app.server.type=${app.server.type}" />
					<jvmarg value="-Ddeployer.unpack.war=${auto.deploy.unpack.war}" />
					<jvmarg value="-Ddeployer.file.pattern=${plugin.name}-*.war" />

					<!-- Optional Arguments -->

					<jvmarg value="-Ddeployer.tomcat.lib.dir=${app.server.tomcat.lib.global.dir}" />

					<!-- Dependent Libraries -->

					<arg value="${app.server.lib.portal.dir}/util-java.jar" />
				</java>
			</then>
			<elseif>
				<antelope:endswith string="${plugin.name}" with="-hook" />
				<then>
					<java
						classname="com.liferay.portal.tools.deploy.HookDeployer"
						classpathref="portal.classpath"
						fork="true"
						newenvironment="true"
					>

						<!-- Required Arguments -->

						<jvmarg value="-Dexternal-properties=com/liferay/portal/tools/dependencies/portal-tools.properties" />
						<jvmarg value="-Dliferay.lib.portal.dir=${app.server.lib.portal.dir}" />
						<jvmarg value="-Ddeployer.base.dir=./dist/latest" />
						<jvmarg value="-Ddeployer.dest.dir=${app.server.deploy.dir}" />
						<jvmarg value="-Ddeployer.app.server.type=${app.server.type}" />
						<jvmarg value="-Ddeployer.unpack.war=${auto.deploy.unpack.war}" />
						<jvmarg value="-Ddeployer.file.pattern=${plugin.name}-*.war" />

						<!-- Optional Arguments -->

						<jvmarg value="-Ddeployer.tomcat.lib.dir=${app.server.tomcat.lib.global.dir}" />

						<!-- Dependent Libraries -->

						<arg value="${app.server.lib.portal.dir}/util-java.jar" />
					</java>
				</then>
			</elseif>
			<elseif>
				<antelope:endswith string="${plugin.name}" with="-layouttpl" />
				<then>
					<java
						classname="com.liferay.portal.tools.deploy.LayoutTemplateDeployer"
						classpathref="portal.classpath"
						fork="true"
						newenvironment="true"
					>

						<!-- Required Arguments -->

						<jvmarg value="-Dexternal-properties=com/liferay/portal/tools/dependencies/portal-tools.properties" />
						<jvmarg value="-Dliferay.lib.portal.dir=${app.server.lib.portal.dir}" />
						<jvmarg value="-Ddeployer.base.dir=./dist/latest" />
						<jvmarg value="-Ddeployer.dest.dir=${app.server.deploy.dir}" />
						<jvmarg value="-Ddeployer.app.server.type=${app.server.type}" />
						<jvmarg value="-Ddeployer.unpack.war=${auto.deploy.unpack.war}" />
						<jvmarg value="-Ddeployer.file.pattern=${plugin.name}-*.war" />
					</java>
				</then>
			</elseif>
			<elseif>
				<antelope:endswith string="${plugin.name}" with="-portlet" />
				<then>
					<java
						classname="com.liferay.portal.tools.deploy.PortletDeployer"
						classpathref="portal.classpath"
						fork="true"
						newenvironment="true"
					>

						<!-- Required Arguments -->

						<jvmarg value="-Dexternal-properties=com/liferay/portal/tools/dependencies/portal-tools.properties" />
						<jvmarg value="-Dliferay.lib.portal.dir=${app.server.lib.portal.dir}" />
						<jvmarg value="-Ddeployer.base.dir=./dist/latest" />
						<jvmarg value="-Ddeployer.dest.dir=${app.server.deploy.dir}" />
						<jvmarg value="-Ddeployer.app.server.type=${app.server.type}" />
						<jvmarg value="-Ddeployer.aui.taglib.dtd=${app.server.portal.dir}/WEB-INF/tld/aui.tld" />
						<jvmarg value="-Ddeployer.portlet.taglib.dtd=${app.server.portal.dir}/WEB-INF/tld/liferay-portlet.tld" />
						<jvmarg value="-Ddeployer.portlet-ext.taglib.dtd=${app.server.portal.dir}/WEB-INF/tld/liferay-portlet-ext.tld" />
						<jvmarg value="-Ddeployer.security.taglib.dtd=${app.server.portal.dir}/WEB-INF/tld/liferay-security.tld" />
						<jvmarg value="-Ddeployer.theme.taglib.dtd=${app.server.portal.dir}/WEB-INF/tld/liferay-theme.tld" />
						<jvmarg value="-Ddeployer.ui.taglib.dtd=${app.server.portal.dir}/WEB-INF/tld/liferay-ui.tld" />
						<jvmarg value="-Ddeployer.util.taglib.dtd=${app.server.portal.dir}/WEB-INF/tld/liferay-util.tld" />
						<jvmarg value="-Ddeployer.unpack.war=${auto.deploy.unpack.war}" />
						<jvmarg value="-Ddeployer.custom.portlet.xml=${auto.deploy.custom.portlet.xml}" />
						<jvmarg value="-Ddeployer.file.pattern=${plugin.name}-*.war" />

						<!-- Optional Arguments -->

						<jvmarg value="-Ddeployer.tomcat.lib.dir=${app.server.tomcat.lib.global.dir}" />

						<!-- Dependent Libraries -->

						<arg value="${app.server.lib.portal.dir}/util-bridges.jar" />
						<arg value="${app.server.lib.portal.dir}/util-java.jar" />
						<arg value="${app.server.lib.portal.dir}/util-taglib.jar" />
					</java>
				</then>
			</elseif>
			<elseif>
				<antelope:endswith string="${plugin.name}" with="-theme" />
				<then>
					<java
						classname="com.liferay.portal.tools.deploy.ThemeDeployer"
						classpathref="portal.classpath"
						fork="true"
						newenvironment="true"
					>

						<!-- Required Arguments -->

						<jvmarg value="-Dexternal-properties=com/liferay/portal/tools/dependencies/portal-tools.properties" />
						<jvmarg value="-Dliferay.lib.portal.dir=${app.server.lib.portal.dir}" />
						<jvmarg value="-Ddeployer.base.dir=./dist/latest" />
						<jvmarg value="-Ddeployer.dest.dir=${app.server.deploy.dir}" />
						<jvmarg value="-Ddeployer.app.server.type=${app.server.type}" />
						<jvmarg value="-Ddeployer.theme.taglib.dtd=${app.server.portal.dir}/WEB-INF/tld/liferay-theme.tld" />
						<jvmarg value="-Ddeployer.util.taglib.dtd=${app.server.portal.dir}/WEB-INF/tld/liferay-util.tld" />
						<jvmarg value="-Ddeployer.unpack.war=${auto.deploy.unpack.war}" />
						<jvmarg value="-Ddeployer.file.pattern=${plugin.name}-*.war" />

						<!-- Optional Arguments -->

						<jvmarg value="-Ddeployer.tomcat.lib.dir=${app.server.tomcat.lib.global.dir}" />

						<!-- Dependent Libraries -->

						<arg value="${app.server.lib.portal.dir}/util-java.jar" />
						<arg value="${app.server.lib.portal.dir}/util-taglib.jar" />
					</java>
				</then>
			</elseif>
		</if>
		<antcall target="deploy-plugin-service" />
		<antcall target="deploy-plugin-common" />
		<antcall target="deploy-plugin-ext" />
	</target>

	<target name="deploy-jsp">
		<if>
			<available file="docroot/css" type="dir" />
			<then>
				<copy todir="${app.server.deploy.dir}/${plugin.name}/css">
					<fileset dir="docroot/css" includes="**" />
				</copy>
			</then>
		</if>
		<if>
			<available file="docroot/html" type="dir" />
			<then>
				<copy todir="${app.server.deploy.dir}/${plugin.name}/html">
					<fileset dir="docroot/html" includes="**" />
				</copy>
			</then>
		</if>
		<if>
			<available file="docroot/jsp" type="dir" />
			<then>
				<copy todir="${app.server.deploy.dir}/${plugin.name}/jsp">
					<fileset dir="docroot/jsp" includes="**" />
				</copy>
			</then>
		</if>
		<copy todir="${app.server.deploy.dir}/${plugin.name}/html">
			<fileset dir="docroot" includes="*.jsp" />
			<fileset dir="docroot" includes="**/*.jsp" />
			<fileset dir="docroot" includes="**/*.jspf" />
		</copy>
		<copy todir="${app.server.deploy.dir}/${plugin.name}">
			<fileset dir="docroot" includes="*.jsp" />
			<fileset dir="docroot" includes="**/*.jsp" />
			<fileset dir="docroot" includes="**/*.jspf" />
		</copy>
		<if>
			<available file="docroot/js" type="dir" />
			<then>
				<copy todir="${app.server.deploy.dir}/${plugin.name}/js">
					<fileset dir="docroot/js" includes="**" />
				</copy>
			</then>
		</if>
	</target>
	
	<target name="merge" if="original.war.file">
		<if>
			<not>
				<uptodate srcfile="${original.war.file}" targetfile="tmp" />
			</not>
			<then>
				<delete dir="tmp" />
				<mkdir dir="tmp" />

				<mkdir dir="tmp/WEB-INF/classes" />
				<mkdir dir="tmp/WEB-INF/lib" />

				<antcall target="merge-unzip" />

				<copy todir="tmp" overwrite="true">
					<fileset dir="docroot" />
				</copy>
			</then>
		</if>

		<copy todir="tmp">
			<fileset dir="docroot" />
		</copy>
	</target>

	<target name="merge-unzip">
		<unzip dest="tmp" src="${original.war.file}" />
	</target>

	<target name="shrink-zip-cmd">
		<tstamp>
			<format property="tstamp.value" pattern="yyyyMMddkkmmssSSS" />
		</tstamp>

		<unzip
			dest="${tstamp.value}"
			src="${zip.file.name}"
		>
			<patternset
				includes="${zip.includes}"
			/>
		</unzip>

		<zip
			basedir="${tstamp.value}"
			destfile="${zip.file.name}"
		/>

		<delete dir="${tstamp.value}" />
	</target>

	<target name="test">
		<delete dir="test-classes" />
		<delete dir="test-results" />

		<antcall target="compile" />
		<antcall target="compile-test" />

		<fileset dir="test-classes" id="test.suite.classes">
			<include name="**/*TestSuite.class" />
		</fileset>

		<pathconvert
			property="test.suite.classes.available"
			refid="test.suite.classes"
			setonempty="false"
		/>

		<if>
			<available file="tmp" />
			<then>
				<path id="plugin-lib.classpath">
					<fileset dir="docroot/WEB-INF/lib" includes="*.jar" />
					<fileset dir="tmp/WEB-INF/lib" includes="*.jar" />
					<pathelement location="docroot/WEB-INF/classes" />
					<pathelement location="tmp/WEB-INF/classes" />
				</path>
			</then>
			<else>
				<path id="plugin-lib.classpath">
					<fileset dir="docroot/WEB-INF/lib" includes="*.jar" />
					<pathelement location="docroot/WEB-INF/classes" />
				</path>
			</else>
		</if>

		<if>
			<not>
				<isset property="test.suite.classes.available" />
			</not>
			<then>
				<junit dir="${project.dir}" fork="on" forkmode="once" haltonfailure="${junit.halt.on.failure}" printsummary="on">
					<sysproperty key="net.sourceforge.cobertura.datafile" file="test-coverage/cobertura.ser" />
					<jvmarg line="${junit.debug.jpda}" />
					<jvmarg value="-Xmx1024m" />
					<jvmarg value="-XX:MaxPermSize=256m" />
					<jvmarg value="-Duser.timezone=GMT" />
					<jvmarg value="-Dexternal-properties=${test.properties}" />
					<classpath location="test-coverage" />
					<classpath refid="test.classpath" />
					<formatter type="brief" usefile="false" />
					<formatter type="xml" />
					<batchtest todir="test-results">
						<fileset dir="test-classes" includes="**/*Test.class" />
					</batchtest>
				</junit>
			</then>
			<else>
				<junit dir="${project.dir}" fork="on" forkmode="once" haltonfailure="${junit.halt.on.failure}" printsummary="on">
					<sysproperty key="net.sourceforge.cobertura.datafile" file="test-coverage/cobertura.ser" />
					<jvmarg line="${junit.debug.jpda}" />
					<jvmarg value="-Xmx1024m" />
					<jvmarg value="-XX:MaxPermSize=256m" />
					<jvmarg value="-Duser.timezone=GMT" />
					<jvmarg value="-Dexternal-properties=${test.properties}" />
					<classpath location="test-coverage" />
					<classpath refid="test.classpath" />
					<formatter type="brief" usefile="false" />
					<formatter type="xml" />
					<batchtest todir="test-results">
						<fileset dir="test-classes" includes="**/*TestSuite.class" />
					</batchtest>
				</junit>
			</else>
		</if>
	</target>

	<target name="test-class" depends="compile,compile-test" if="class">
		<junit dir="${project.dir}" fork="on" forkmode="once" outputtoformatters="false" printsummary="on" showoutput="true">
			<sysproperty key="net.sourceforge.cobertura.datafile" file="test-coverage/cobertura.ser" />
			<jvmarg line="${junit.debug.jpda}" />
			<jvmarg value="-Xmx1024m" />
			<jvmarg value="-XX:MaxPermSize=256m" />
			<jvmarg value="-Duser.timezone=GMT" />
			<jvmarg value="-Dexternal-properties=${test.properties}" />
			<classpath location="test-coverage" />
			<classpath refid="test.classpath" />
			<formatter type="brief" usefile="false" />
			<formatter type="xml" />
			<batchtest todir="test-results">
				<fileset dir="test-classes" includes="**/${class}.class" />
			</batchtest>
		</junit>
	</target>

	<target name="undeploy-liferay" depends="check-liferay-deploy" if="foundDeploy">
		<delete failonerror="false" includeEmptyDirs="true">
			<fileset dir="${auto.deploy.dir}" includes="${plugin.name}*"/> 
		</delete>
	</target>

	<target name="undeploy" depends="undeploy-liferay">
		<delete dir="${app.server.deploy.dir}/${plugin.name}" />
	</target>
	
	<target name="war" depends="compile">
		<antcall target="jar-plugin-src" />
		<if>
			<available file="docroot/WEB-INF/ext/classes" type="dir" />
			<then>
				<antcall target="jar-plugin-ext" />
			</then>
		</if>
		<mkdir dir="${project.dir}/dist" />
		<mkdir dir="dist/latest" />
		
		<if>
			<equals arg1="${create.dist.dev}" arg2="true" />
			<then>
				<mkdir dir="dist/${plugin.version}" />
			</then>
		</if>

		<if>
			<available file="tmp" />
			<then>
				<property name="docroot.dir" value="tmp" />
			</then>
			<else>
				<property name="docroot.dir" value="docroot" />
			</else>
		</if>

		<delete file="${plugin.file}" />
		<delete file="${plugin.latest.file}" />
		
		<if>
			<equals arg1="${create.dist.dev}" arg2="true" />
			<then>
				<delete file="${plugin.local.file}" />
			</then>
		</if>

		<antcall target="clean-portal-dependencies" />
		
		<if>
			<contains string="${app.server.dir}" substring="glassfish" />
			<then>
				<zip
					basedir="${docroot.dir}"
					destfile="${plugin.file}"
					excludes="**/META-INF/context.xml,${plugins.war.excludes}"
				/>
				<if>
					<equals arg1="${create.dist.dev}" arg2="true" />
					<then>
						<zip
							basedir="${docroot.dir}"
							destfile="${plugin.local.file}"
							excludes="**/META-INF/context.xml,${plugins.war.excludes}"
						/>
					</then>
				</if>
			</then>
			<else>
				<if>
					<equals arg1="${create.dist.dev}" arg2="true" />
					<then>
						<zip
							basedir="${docroot.dir}"
							destfile="${plugin.file}"
							excludes="${plugins.war.excludes},**/struts-config-ext.xml,**/portlet-ext.xml,**/liferay-portlet-ext.xml,**/tiles-defs-ext.xml"
						/>
					</then>
				</if>
				<zip
					basedir="${docroot.dir}"
					destfile="${plugin.latest.file}"
					excludes="${plugins.war.excludes},**/struts-config-ext.xml,**/portlet-ext.xml,**/liferay-portlet-ext.xml,**/tiles-defs-ext.xml"
				/>
			</else>
		</if>
		<!--<antcall target="copy-service-to-dist" />
		<antcall target="copy-common-to-dist" />-->
	</target>

	<!--target name="jar-plugin-ext">
		<if>
			<available file="docroot/WEB-INF/ext/classes" type="dir" />
			<then>
				<if>
					<available file="docroot/WEB-INF/liferay-hook.xml" />
					<then>
						<echo message="read property from liferay-hook.xml"/>
						<xmltask source="docroot/WEB-INF/liferay-hook.xml">
							<copy path="//hook/custom-jsp-dir/text()" property="destDir" />
						</xmltask>
					</then>
					<else>
						<property name="destDir" value="/custom" />
					</else>
				</if>
				<echo>Create extension jar for hook and put it into docroot${destDir}/WEB-INF/lib</echo>
				<mkdir dir="docroot/${destDir}/WEB-INF/lib" />
				<property name="plugin-ext.file" value="ext-${plugin.name}-${lp.version}.jar" />
				<delete>
					<fileset dir="docroot${destDir}/WEB-INF/lib/" includes="**/*${plugin.name}*.jar" />
					<fileset dir="docroot/WEB-INF/lib/" includes="**/ext-${plugin.name}*.jar" />
				</delete>
				<jar destfile="docroot${destDir}/WEB-INF/lib/${plugin-ext.file}">
					<fileset dir="docroot/WEB-INF/ext/classes" />
				</jar>
				<copy todir="${project.dir}/lib">
                    <fileset dir="docroot${destDir}/WEB-INF/lib/" includes="${plugin-ext.file}" />
                </copy>
				<copy todir="docroot/WEB-INF/lib">
	                <fileset dir="docroot${destDir}/WEB-INF/lib/" includes="${plugin-ext.file}" />
	            </copy>
			</then>
		</if>
	</target-->
	
	<target name="jar-plugin-ext">
		<if>
			<available file="docroot/WEB-INF/ext/classes" type="dir" />
			<then>
				<if>
					<available file="docroot/WEB-INF/liferay-hook.xml" />
					<then>
						<echo message="read property from liferay-hook.xml"/>
						<xmltask source="docroot/WEB-INF/liferay-hook.xml">
							<xmlcatalog refid="dtds"/>
							<copy path="//hook/custom-jsp-dir/text()" property="destDir" />
						</xmltask>
					</then>
					<else>
						<property name="destDir" value="/custom" />
					</else>
				</if>
				<echo>Create extension jar for hook and put it into docroot${destDir}/WEB-INF/lib</echo>
				<mkdir dir="docroot/${destDir}/WEB-INF/lib" />

				<property name="plugin-ext.file" value="ext-${plugin.name}-${lp.version}.jar" />
				<delete>
					<fileset dir="docroot/WEB-INF/lib/" includes="**/ext-${plugin.name}*.jar" />
				</delete>
				<jar destfile="${project.dir}/lib/${plugin-ext.file}">
					<fileset dir="docroot/WEB-INF/ext/classes" />
				</jar>
				<!--jar destfile="docroot/WEB-INF/lib/${plugin-ext.file}">
					<fileset dir="docroot/WEB-INF/ext/classes" />
				</jar-->
				<jar destfile="docroot${destDir}/WEB-INF/lib/${plugin-ext.file}">
					<fileset dir="docroot/WEB-INF/ext/classes" />
				</jar>
			</then>
		</if>
	</target>
	
	<target name="jar-plugin-common" depends="compile-plugin-common">
		<if>
			<available file="docroot/WEB-INF/common/classes" type="dir" />
			<then>
				<echo>Create common jar for plugin</echo>
				
				<property name="plugin-common.file" value="ep-common-${plugin.name}.jar" />
				
				<if>
						<available file="dist/latest/common" type="dir" />
						<then>
							<delete>
								<fileset dir="dist/latest/common/" includes="**/${plugin-common.file}" />
								<fileset dir="${project.dir}/lib/" includes="**/${plugin-common.file}" />
							</delete>
						</then>
				</if>
				
				<jar destfile="${project.dir}/lib/${plugin-common.file}">
					<fileset dir="docroot/WEB-INF/common/classes" />
				</jar>
				
				<antcall target="copy-common-to-dist" />
				
				<!-- <jar destfile="docroot/WEB-INF/lib/${plugin-common.file}">
					<fileset dir="docroot/WEB-INF/common/classes" />
				</jar> -->
			</then>
		</if>
	</target>
	
	<target name="jar-plugin-src">
		<if>
			<available file="docroot/WEB-INF/classes/META-INF/portlet-spring.xml" />
			<then>
				<echo>Create src jar for plugin</echo>
				
				<property name="plugin-src.file" value="ep-src-${plugin.name}.jar" />
				
				<if>
						<available file="dist/latest/src" type="dir" />
						<then>
							<delete>
								<fileset dir="dist/latest/src/" includes="**/${plugin-src.file}" />
							</delete>
						</then>
				</if>
				
				<mkdir dir="docroot/WEB-INF/src-classes" />
				<mkdir dir="docroot/WEB-INF/src-classes/META-INF" />
				
				<copy todir="docroot/WEB-INF/src-classes" overwrite="true">
					<fileset dir="docroot/WEB-INF/classes/" includes="**/*.class" />
					<fileset dir="docroot/WEB-INF/classes/" includes="service.properties" />
				</copy>
				
				<copy file="docroot/WEB-INF/classes/META-INF/portlet-hbm.xml" tofile="docroot/WEB-INF/src-classes/META-INF/${plugin.name}-portlet-hbm.xml" />
				<copy file="docroot/WEB-INF/classes/META-INF/portlet-spring.xml" tofile="docroot/WEB-INF/src-classes/META-INF/${plugin.name}-portlet-spring.xml" />
				<if>
					<available file="docroot/WEB-INF/liferay-hook.xml"/>
					<then>
						<copy file="docroot/WEB-INF/liferay-hook.xml" tofile="docroot/WEB-INF/src-classes/${plugin.name}-liferay-hook.xml" />
					</then>
				</if>
				<if>
					<available file="docroot/WEB-INF/classes/portal.properties"/>
					<then>
						<copy file="docroot/WEB-INF/classes/portal.properties" tofile="docroot/WEB-INF/src-classes/${plugin.name}-portal.properties" />
					</then>
				</if>
				<if>
					<available file="docroot/WEB-INF/classes/portal-ext.properties"/>
					<then>
						<copy file="docroot/WEB-INF/classes/portal-ext.properties" tofile="docroot/WEB-INF/src-classes/${plugin.name}-portal-ext.properties" />
					</then>
				</if>
				
				<zip
					basedir="docroot/WEB-INF/src-classes"
					destfile="docroot/WEB-INF/src-classes/${plugin-src.file}"
				/>

				<mkdir dir="dist/latest/src" />

				<copy todir="dist/latest/src">
					<fileset dir="docroot/WEB-INF/src-classes/" includes="${plugin-src.file}" />
				</copy>
				
				<if>
					<equals arg1="${create.dist.dev}" arg2="true" />
					<then>
						<mkdir dir="dist/${plugin.version}/src" />
				        <copy todir="dist/${plugin.version}/src">
				        	<fileset dir="docroot/WEB-INF/src-classes/" includes="${plugin-src.file}" />
						</copy>
					</then>
				</if>

				<delete dir="docroot/WEB-INF/src-classes" />
			</then>
		</if>
	</target>
	
	<target name="compile-java" depends="build-common.compile-java"/>
	
	
	<target name="vz" description="copy war to tomcat on vm">

       <scp todir="root:abc123_@192.168.179.116:/usr/local/tomcat7/deploy" trust="true">

           <fileset dir="dist/latest" includes="${plugin.name}*.war"/>

       </scp>

    </target>
	
	<target name="vzsc" description="copy war,service.jar,common.jar to tomcat on vm" depends="vz">
		<if>
			<available file="dist/latest/common/ep-common-${plugin.name}.jar" />
			<then>
			 <scp todir="root:abc123_@192.168.179.116:/usr/local/tomcat7/tomcat/lib/ext" trust="true">
				<fileset dir="dist/latest/common" includes="ep-common-${plugin.name}.jar"/>
			</scp>
			</then>
		</if>
		
		<if>
			<available file="dist/latest/service/${plugin.name}-service.jar" />
			<then>
			<scp todir="root:abc123_@192.168.179.116:/usr/local/tomcat7/tomcat/lib/ext" trust="true">
				<fileset dir="dist/latest/service" includes="${plugin.name}-service.jar"/>
			</scp>
			</then>
		</if>
    </target>

    

    <target name="fullvz" description="clean build-service deploy vz">

       <antcall target="clean" />

       <antcall target="build-service" />

       <antcall target="deploy" />

       <antcall target="vz" />

    </target>

	<target name="rmli" description="remove licenses to deploy">
	  
	  <scp todir="root:abc123_@192.168.179.116:/usr/local/tomcat7/deploy" trust="true">

           <fileset dir="${project.dir}/../licenses" includes="license-portaldevelopment-developer-6.1-endplayinc.xml"/>

       </scp>
    </target>


</project>
2013-05-07 19:41:59
#set ($thirdPartyLocalService= $portletBeanLocator.locate("third-party-portlet", "com.endplay.thirdparty.service.ThirdPartyLocalService"))  
二〇一三年五月六日 19:14:10
鄂尔多斯、

JMS
SMTP 、

JavaMail
http://ejbvn.wordpress.com/category/week-3-advanced-ejb-applications/day-20-implementing-javamail-in-ejb-applications/ JMS 和 javaMail区别
列子:http://www.iteye.com/topic/352753 
张孝祥也有将javamail的视频
和 
Java邮件开发详解 张孝祥


--------------------------------------------------------------------------------


ExtVelocityVariablesImpl  这个东西是写hook还是ext?外部velocityContext.put("dateTool", new DateTool());  这个的DateTool() 怎么导入?

<bean id="com.liferay.portal.kernel.velocity.VelocityVariablesUtil" class="com.liferay.portal.kernel.velocity.VelocityVariablesUtil">
        <property name="velocityVariables">
            <bean class="com.endplay.portal.kernel.velocity.ExtVelocityVariablesImpl" />
           </property>
    </bean> 

ImportLocalServiceImpl-2013-03-14 11:01:51
package com.endplay.dataimport.portlet.service.impl;

import au.com.bytecode.opencsv.CSVReader;

import com.endplay.dataimport.portlet.service.base.ImportLocalServiceBaseImpl;
import com.endplay.dataimport.util.ImportResults;
import com.endplay.dataimport.util.ImportUtil;
import com.endplay.portlet.asset.EPCategoryEnum;
import com.endplay.portlet.collection.CollectionDataBean;
import com.endplay.portlet.collection.CollectionDataUtil;
import com.endplay.portlet.collection.CollectionEntryBean;
import com.endplay.portlet.custom.util.CustomFieldDataUtil;
import com.endplay.portlet.epdata.media.configuration.ConfigurationPropertyConstants;
import com.endplay.portlet.group.GroupUtil;
import com.endplay.portlet.journal.util.JournalArticleDataUtil;
import com.liferay.counter.service.CounterLocalServiceUtil;
import com.liferay.portal.DuplicateOrganizationException;
import com.liferay.portal.DuplicateRoleException;
import com.liferay.portal.DuplicateUserEmailAddressException;
import com.liferay.portal.DuplicateUserScreenNameException;
import com.liferay.portal.LayoutFriendlyURLException;
import com.liferay.portal.NoSuchGroupException;
import com.liferay.portal.NoSuchLayoutException;
import com.liferay.portal.NoSuchOrganizationException;
import com.liferay.portal.kernel.dao.orm.QueryUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.language.LanguageUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
import com.liferay.portal.kernel.staging.StagingUtil;
import com.liferay.portal.kernel.templateparser.TemplateNode;
import com.liferay.portal.kernel.util.ContentTypes;
import com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.HtmlUtil;
import com.liferay.portal.kernel.util.HttpUtil;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.LocalizationUtil;
import com.liferay.portal.kernel.util.MathUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.UnicodeProperties;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import com.liferay.portal.kernel.xml.Document;
import com.liferay.portal.kernel.xml.DocumentException;
import com.liferay.portal.kernel.xml.Element;
import com.liferay.portal.kernel.xml.SAXReaderUtil;
import com.liferay.portal.model.Group;
import com.liferay.portal.model.GroupConstants;
import com.liferay.portal.model.Image;
import com.liferay.portal.model.Layout;
import com.liferay.portal.model.LayoutConstants;
import com.liferay.portal.model.LayoutPrototype;
import com.liferay.portal.model.LayoutSetPrototype;
import com.liferay.portal.model.LayoutTypePortlet;
import com.liferay.portal.model.ListType;
import com.liferay.portal.model.ModelHintsUtil;
import com.liferay.portal.model.Organization;
import com.liferay.portal.model.OrganizationConstants;
import com.liferay.portal.model.PortletConstants;
import com.liferay.portal.model.PortletPreferences;
import com.liferay.portal.model.ResourceConstants;
import com.liferay.portal.model.Role;
import com.liferay.portal.model.User;
import com.liferay.portal.service.GroupLocalServiceUtil;
import com.liferay.portal.service.ImageLocalServiceUtil;
import com.liferay.portal.service.LayoutServiceUtil;
import com.liferay.portal.service.ListTypeServiceUtil;
import com.liferay.portal.service.ServiceContext;
import com.liferay.portal.service.permission.PortletPermissionUtil;
import com.liferay.portal.util.PortalUtil;
import com.liferay.portal.util.PortletKeys;
import com.liferay.portal.webserver.WebServerServletTokenUtil;
import com.liferay.portlet.asset.DuplicateCategoryException;
import com.liferay.portlet.asset.NoSuchCategoryException;
import com.liferay.portlet.asset.NoSuchVocabularyException;
import com.liferay.portlet.asset.model.AssetCategory;
import com.liferay.portlet.asset.model.AssetVocabulary;
import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
import com.liferay.portlet.asset.service.AssetCategoryServiceUtil;
import com.liferay.portlet.asset.service.AssetVocabularyLocalServiceUtil;
import com.liferay.portlet.asset.service.persistence.AssetCategoryFinderUtil;
import com.liferay.portlet.documentlibrary.DuplicateFileEntryTypeException;
import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
import com.liferay.portlet.dynamicdatalists.model.DDLRecord;
import com.liferay.portlet.dynamicdatalists.model.DDLRecordConstants;
import com.liferay.portlet.dynamicdatalists.model.DDLRecordSet;
import com.liferay.portlet.dynamicdatalists.model.DDLRecordSetConstants;
import com.liferay.portlet.dynamicdatalists.model.DDLRecordVersion;
import com.liferay.portlet.dynamicdatamapping.NoSuchStructureException;
import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
import com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants;
import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
import com.liferay.portlet.dynamicdatamapping.storage.Fields;
import com.liferay.portlet.dynamicdatamapping.storage.StorageEngineUtil;
import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
import com.liferay.portlet.expando.DuplicateColumnNameException;
import com.liferay.portlet.expando.NoSuchTableException;
import com.liferay.portlet.expando.model.ExpandoColumn;
import com.liferay.portlet.expando.model.ExpandoTable;
import com.liferay.portlet.journal.NoSuchArticleException;
import com.liferay.portlet.journal.model.JournalArticle;
import com.liferay.portlet.journal.model.JournalArticleConstants;
import com.liferay.portlet.journal.model.JournalContentSearch;
import com.liferay.portlet.journal.model.JournalStructure;
import com.liferay.portlet.journal.model.JournalTemplate;
import com.liferay.portlet.journal.service.JournalArticleImageLocalServiceUtil;
import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
import com.liferay.portlet.journal.service.JournalStructureLocalServiceUtil;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

/**
 * The implementation of the import local service.
 * 
 * <p>
 * All custom service methods should be put in this class. Whenever methods are
 * added, rerun ServiceBuilder to copy their definitions into the
 * {@link com.endplay.dataimport.portlet.service.ImportLocalService} interface.
 * 
 * <p>
 * This is a local service. Methods of this service will not have security
 * checks based on the propagated JAAS credentials because this service can only
 * be accessed from within the same VM.
 * </p>
 * 
 * @author Harry Mark
 * @see com.endplay.dataimport.portlet.service.base.ImportLocalServiceBaseImpl
 * @see com.endplay.dataimport.portlet.service.ImportLocalService
 */
public class ImportLocalServiceImpl extends ImportLocalServiceBaseImpl {

	public static final String GLOBAL_GROUP = "Global";

	private static Log _log = LogFactoryUtil.getLog(ImportLocalServiceImpl.class);

	private final boolean IS_FROM_SIBLING = true;
	private final boolean IS_NOT_FROM_SIBLING = false;

	public Group getGroup(long companyId, String name) throws Exception {
		String finalGroupName = name;

		// if global group, use companyId as name
		if (finalGroupName.equals(GLOBAL_GROUP)) {
			finalGroupName = Long.toString(companyId);
		}

		Group group = null;

		try {
			group = groupLocalService.getGroup(companyId, finalGroupName);
		} catch (NoSuchGroupException nsg) {
			// search for Organization with the same name
			Organization org = null;

			try {
				org = organizationLocalService.getOrganization(companyId, finalGroupName);

				group = org.getGroup();
			} catch (NoSuchOrganizationException nso) {
				// throw the original group not found error
				throw nsg;
			}
		}

		// check for staging group, return it if found
		if (group != null && group.hasStagingGroup()) {
			return group.getStagingGroup();
		}

		return group;
	}

	public Group getStagingGroup(long companyId, String name) throws Exception {

		try {
			Group group = groupLocalService.getGroup(companyId, name);

			if (group.hasStagingGroup()) {
				return group.getStagingGroup();
			}
		} catch (NoSuchGroupException ex) {
		}

		return null;
	}

	protected String getDisplayName(Group group) {
		String display = "'";

		if (group.getClassPK() == group.getCompanyId()) {
			display += GLOBAL_GROUP;
		} else {
			display += group.getName();
		}

		return display + "'";
	}

	public AssetCategory getCategory(long groupId, long companyId, String name) throws Exception {
		return getCategory(groupId, companyId, name, 0);
	}

	public AssetCategory getCategory(long groupId, long companyId, String name, long vocabularyId) throws Exception {
		List<AssetCategory> categories = null;

		if (vocabularyId != 0) {
			categories = assetCategoryPersistence.findByG_V(groupId, vocabularyId);
		} else {
			categories = assetCategoryPersistence.findByGroupId(groupId);
		}

		for (AssetCategory category : categories) {
			if (category.getName().equals(name)) {
				return category;
			}
		}

		// check the global group if not found in the group's categories
		groupId = getGroup(companyId, GLOBAL_GROUP).getGroupId();

		if (vocabularyId != 0) {
			categories = assetCategoryPersistence.findByG_V(groupId, vocabularyId);
		} else {
			categories = assetCategoryPersistence.findByGroupId(groupId);
		}

		for (AssetCategory category : categories) {
			if (category.getName().equals(name)) {
				return category;
			}
		}

		throw new Exception("Category " + name + " not found in group or Global group.");
	}

	public AssetCategory createCategory(User user, ImportResults log, Group group, String name, String description,
			String vocabulary, String parentCategory, String globalCategoryName, String staticCategoryId)
			 throws Exception{
		ServiceContext serviceContext = new ServiceContext();
		serviceContext.setScopeGroupId(group.getGroupId());
		serviceContext.setCompanyId(group.getCompanyId());

		long vocabularyId = 0;

		AssetVocabulary vocabObj = null;
		if (vocabulary != null && !vocabulary.isEmpty()) {
			try {
				vocabObj = assetVocabularyLocalService.getGroupVocabulary(group.getGroupId(), vocabulary);
			} catch (NoSuchVocabularyException nsv) {
				String vocabDescription = "";
				String settings = "multiValued=true\nselectedClassNameIds=0\n";

				// create new vocabulary
				vocabObj = assetVocabularyLocalService.addVocabulary(user.getUserId(), vocabulary,
						ImportUtil.toMap(vocabulary), ImportUtil.toMap(vocabDescription), settings, serviceContext);

				log.add("Created vocabulary '" + vocabulary + "' for " + getDisplayName(group));
			}

			vocabularyId = vocabObj.getVocabularyId();
		} else {
			// choose the default vocabulary
			List<AssetVocabulary> vocabs = assetVocabularyLocalService.getGroupVocabularies(group.getGroupId());

			vocabularyId = Long.MAX_VALUE;
			for (AssetVocabulary vocab : vocabs) {
				if (vocab.getVocabularyId() < vocabularyId) {
					vocabularyId = vocab.getVocabularyId();
				}
			}
		}

		// look up parentcategory
		long parentCategoryId = 0;

		if (parentCategory != null && parentCategory.length() > 0) {
			// List<AssetCategory> categories =
			// assetCategoryLocalService.getChildCategories(parentCategoryId);
			//
			// for (AssetCategory category : categories) {
			// if (category.getGroupId() == groupId &&
			// category.getTitle(Locale.getDefault()).equalsIgnoreCase(parentCategory))
			// {
			// parentCategoryId = category.getCategoryId();
			// break;
			// }
			// }

		    AssetCategory parentCatg = this.getTargetCategory(group, parentCategory, vocabularyId);
		    if (parentCatg != null) {
		        parentCategoryId = parentCatg.getCategoryId();
		    }

			if (parentCategoryId == 0) {
				throw new Exception("Parent category " + parentCategory + " not found");
			}
		}

		AssetVocabulary vocab = assetVocabularyLocalService.getAssetVocabulary(vocabularyId);

		String[] categoryProperties = new String[0];

		// check if global category needed. global category is required if not
		// in global group.
		if (!Long.toString(group.getCompanyId()).equals(group.getName())) {
			if (StringUtils.isBlank(globalCategoryName)) {
				throw new Exception("Global Category required to be associated with a non-Global category: " + name);
			} else {
				Group globalGroup = groupLocalService.getGroup(group.getCompanyId(),
						Long.toString(group.getCompanyId()));
				AssetVocabulary globalVocab = assetVocabularyLocalService.getGroupVocabulary(globalGroup.getGroupId(), vocabulary);
				AssetCategory globalCategory = this.getTargetCategory(globalGroup, globalCategoryName, globalVocab.getVocabularyId());
				if (globalCategory == null) {
				    throw new Exception("Global category " + globalCategoryName + " not found");
				}
				
				categoryProperties = new String[2];
				categoryProperties[0] = EPCategoryEnum.GLOBAL_CATEGORY_ID.getName() + ":"
						+ globalCategory.getCategoryId();
				// categoryProperties[1] =
				// EPCategoryEnum.GLOBAL_CATEGORY_NAME.getName() + ":" +
				// globalCategory.getName();
			}
		} else { // is global category
			// add static category Id
			if (StringUtils.isNotBlank(staticCategoryId)) {
				categoryProperties = new String[1];
				categoryProperties[0] = EPCategoryEnum.STATIC_CATEGORY_ID.getName() + ":" + staticCategoryId;
			}
		}

		AssetCategory category = null;

		try {
			category = assetCategoryLocalService.addCategory(user.getUserId(), parentCategoryId,
					ImportUtil.toMap(name), ImportUtil.toMap(description), vocabularyId, categoryProperties,
					serviceContext);

			String msg = "Create category '" + name + "' in '" + vocab.getTitle(Locale.getDefault() + "'");
			log.add(msg);
			_log.info(msg);
		} catch (DuplicateCategoryException dce) {
			log.add("Category '" + name + "' already exists in '" + vocab.getTitle(Locale.getDefault()) + "'");

			// get existing
			category = assetCategoryPersistence.fetchByP_N_V(parentCategoryId, name, vocabularyId);

			// update staging/global group category properties
			category = assetCategoryLocalService.updateCategory(category.getUserId(), category.getCategoryId(),
					category.getParentCategoryId(), category.getTitleMap(), category.getDescriptionMap(),
					category.getVocabularyId(), categoryProperties, serviceContext);
			
			// update live group category properties
			if (!Long.toString(group.getCompanyId()).equals(group.getName())) {
	            if (group.isStagingGroup()) {
	                Group liveGroup = group.getLiveGroup();

	                ServiceContext liveServiceContext = new ServiceContext();

	                liveServiceContext.setScopeGroupId(liveGroup.getGroupId());
	                liveServiceContext.setCompanyId(liveGroup.getCompanyId());;

	                AssetCategory stagParentCategory = AssetCategoryLocalServiceUtil.fetchCategory(parentCategoryId);
	                AssetVocabulary assetVocabulary = AssetVocabularyLocalServiceUtil.getAssetVocabulary(vocabularyId);
	                AssetVocabulary liveVocabulary = AssetVocabularyLocalServiceUtil.getAssetVocabularyByUuidAndGroupId(assetVocabulary.getUuid(), liveGroup.getGroupId());
	                long liveParentCategoryId = 0;
	                if (stagParentCategory != null) {
	                    AssetCategory liveParentCategory = AssetCategoryLocalServiceUtil.getAssetCategoryByUuidAndGroupId(stagParentCategory.getUuid(), liveGroup.getGroupId());
	                    liveParentCategoryId = liveParentCategory.getCategoryId();
	                }

	                AssetCategory liveCategory;
                    try {
                        liveCategory = AssetCategoryLocalServiceUtil.getAssetCategoryByUuidAndGroupId(category.getUuid(), liveGroup.getGroupId());
                        if (liveCategory != null) {
                            liveCategory = assetCategoryLocalService.updateCategory(category.getUserId(), liveCategory.getCategoryId(),
                                liveParentCategoryId, category.getTitleMap(), category.getDescriptionMap(),
                                liveVocabulary.getVocabularyId(), categoryProperties, serviceContext);
                        }
                    } catch (NoSuchCategoryException e) {
                        ServiceContext newServiceContext = new ServiceContext();

                        newServiceContext.setUuid(category.getUuid());
                        newServiceContext.setAddGroupPermissions(true);
                        newServiceContext.setAddGuestPermissions(true);
                        newServiceContext.setCreateDate(category.getCreateDate());
                        newServiceContext.setModifiedDate(category.getModifiedDate());
                        newServiceContext.setScopeGroupId(liveGroup.getGroupId());
                        liveCategory = AssetCategoryServiceUtil.addCategory(
                            liveParentCategoryId, category.getTitleMap(), category.getDescriptionMap(), liveVocabulary.getVocabularyId(),
                            categoryProperties, newServiceContext);
                    }

	                
	            }
			}
		}

		return category;
	}

	private AssetCategory getTargetCategory(Group group, String name, long vocabularyId) throws Exception{
	    // process category with level
	    String[] catgNames = name.split("\\|");
	    AssetCategory targetCategory = null;
	    for (int i = 0; i < catgNames.length; i ++) {
	        String catgName = catgNames[i];
	        if (i == 0){
	            targetCategory = assetCategoryPersistence.fetchByP_N_V(0, catgName, vocabularyId);
	        } else {
	            if (targetCategory != null) {
	                targetCategory = assetCategoryPersistence.fetchByP_N_V(targetCategory.getCategoryId(), catgName, vocabularyId);
	            }
	        }
	    }
	    
	    // for compatible old pattern(category with no level)
	    if (catgNames.length == 1 && targetCategory == null) {
	        targetCategory = AssetCategoryFinderUtil.findByG_N(group.getGroupId(), catgNames[0]);
	    }
	    
	    return targetCategory;
	}
	
	public ExpandoColumn createCustomField(long companyId, ImportResults log, String className, String tableName,
			String columnName, int type, Object defaultData, String typeSettings) throws Exception {

		ExpandoTable expandoTable = null;

		try {
			expandoTable = expandoTableLocalService.getTable(className, tableName);
		} catch (NoSuchTableException nst) {
			expandoTable = expandoTableLocalService.addTable(className, tableName);
		}

		if (expandoTable == null) {
			expandoTable = createExpandoTable(companyId, className, tableName);
		}

		long tableId = expandoTable.getTableId();

		ExpandoColumn expandoColumn = expandoColumnLocalService.getColumn(tableId, columnName);

		log.add("Create custom field '" + columnName + "' in " + tableName + " for " + className);

		if (expandoColumn == null) {
			expandoColumn = createExpandoColumn(log, tableId, columnName, type, defaultData, typeSettings);
		} else {
			log.add("Custom field already exists.");
		}

		return expandoColumn;
	}

	protected ExpandoColumn createExpandoColumn(ImportResults log, long tableId, String name, int type,
			Object defaultData, String typeSettings) throws Exception {

		ExpandoColumn column = null;

		try {
			column = expandoColumnLocalService.addColumn(tableId, name, type);
		} catch (DuplicateColumnNameException e) {
			log.add("Custom field '" + name + "' already exists.");

			column = expandoColumnLocalService.getColumn(tableId, name);
		}

		expandoColumnLocalService.updateTypeSettings(column.getColumnId(), typeSettings);

		expandoColumnLocalService.updateColumn(column.getColumnId(), name, type, defaultData);

		return column;
	}

	protected ExpandoTable createExpandoTable(long companyId, String className, String name) throws Exception {

		ExpandoTable table = null;

		try {
			table = expandoTableLocalService.getTable(companyId, className, name);
		} catch (Exception e) {
			table = expandoTableLocalService.addTable(companyId, className, name);
		}

		return table;
	}

	public Group createGroup(User user, ImportResults log, String name, String description, int type,
			String friendlyURL, Boolean staging, String typeSettings, String rowId) throws Exception {
		ServiceContext serviceContext = new ServiceContext();
		boolean site = true;
		boolean active = true;
		boolean isStaging = false;

		if ((staging != null) && (staging.booleanValue())) {
			if (StringUtils.isBlank(typeSettings)) {
				log.add("Group(" + name + ") Staging needs TypeSettings to be set @ " + rowId);
			} else {
				isStaging = true;
			}
		}

		if (isStaging) {
			log.add("Create live group '" + name + "'");
		} else {
			log.add("Create group '" + name + "'");
		}

		Group group = null;
		try {
		    // try updating group to enable staging
		    group = this.updateGroup(user, log, name, description, type, friendlyURL, isStaging, typeSettings);
		    
		} catch (NoSuchGroupException nsge) {
		    // try creating live group first
            group = groupLocalService.addGroup(user.getUserId(), null, 0, GroupConstants.DEFAULT_LIVE_GROUP_ID, name,
                    description, type, friendlyURL, site, active, serviceContext);

            if (isStaging) {
                group.setTypeSettings(typeSettings);
                groupLocalService.updateGroup(group);

                // create staging group
                StagingUtil.enableLocalStaging(user.getUserId(), null, group, false, false, serviceContext);
                
                log.add("'" + group.getStagingGroup().getName() + "' created.");
            }
		} catch (Exception e) {
			log.add("Failed to create or update group '" + name + "'");
		}

		return group;
	}

	/**
	 * update group to enable staging
	 */
	
	protected Group updateGroup(User user, ImportResults log, String name, String description, int type,
            String friendlyURL, Boolean isStaging, String typeSettings) throws Exception {
	    ServiceContext serviceContext = new ServiceContext();
	    boolean active = true;
	    
	    Group group = groupLocalService.getGroup(user.getCompanyId(), name);
        
        // try updating live group first
        group = groupLocalService.updateGroup(group.getGroupId(), name, description, type, friendlyURL, active, serviceContext);
        if (isStaging) {
            log.add("Live group '" + name + "' alreay exists, create Staging for Group(" + name + ").");
            
            group.setTypeSettings(typeSettings);
            groupLocalService.updateGroup(group);

            // create staging group
            StagingUtil.enableLocalStaging(user.getUserId(), null, group, false, false, serviceContext);
            
            log.add("'" + group.getStagingGroup().getName() + "' created.");
        } else {
            log.add("Update group '" + name + "'");
        }
	    
	    return group;
	}
	
	// public Layout createLayout(User user, ImportResults log, List<String>
	// stageLayoutUrls, String groupName, String name, String description,
	// String friendlyUrl, Boolean private_,
	// Boolean hidden, String parentFriendlyUrl, String theme, String
	// colorSchemeId, String layoutTemplate, String addTypeSettings, long[]
	// categoryIds,
	// String column1Portlets, String column2Portlets,
	// String column3Portlets, String column4Portlets, String column5Portlets,
	// String column6Portlets, String column7Portlets, String column8Portlets,
	// String column9Portlets, boolean updateIfExists) throws Exception {
	public Layout createLayout(User user, ImportResults log, List<String> stageLayoutUrls, String groupName,
			String name, String description, String friendlyUrl, String type, Boolean private_, Boolean hidden,
			String parentFriendlyUrl, String theme, String colorSchemeId, String layoutTemplate,
			String addTypeSettings, long[] categoryIds, List<String[]> columnPortlets, boolean updateIfExists,
			boolean alwaysUpdateMetadata, Map<String, String> customFields) throws Exception {

		long companyId = user.getCompanyId();

		Group group = getGroup(companyId, groupName);

		String title = null;

		long parentLayoutId = getParentLayoutId(group, parentFriendlyUrl, private_);

		if (StringUtils.isBlank(type)) {
			type = LayoutConstants.TYPE_PORTLET;
		}

		// Layout layout = createLayout(user, log, group, private_,
		// parentLayoutId, name, title, description, type,
		// hidden, friendlyUrl, theme, colorSchemeId, layoutTemplate,
		// categoryIds, updateIfExists);

		// check if layout already exists
		Layout layout = null;

		try {
			layout = layoutLocalService.getFriendlyURLLayout(group.getGroupId(), private_, friendlyUrl);

			String msgStart = "Layout '" + name + "' for " + getDisplayName(group) + " already exists ... ";

			// update
			// only update if updateIfExists is set
			if (updateIfExists) {
				log.add(msgStart + "updating");

				layout = updateLayout(layout.getPlid(), name, description, private_, hidden, parentLayoutId, theme,
						colorSchemeId, layoutTemplate);

				deleteAllPortlets(layout.getPlid(), user.getUserId());
			} else {
				log.add(msgStart + "leaving as is");
			}
		} catch (NoSuchLayoutException nsl) {
			ServiceContext serviceContext = new ServiceContext();
			serviceContext.setAssetCategoryIds(categoryIds);

			log.add("Create layout '" + name + "' for " + getDisplayName(group));
			layout = layoutLocalService.addLayout(user.getUserId(), group.getGroupId(), private_, parentLayoutId, name,
					title, description, type, hidden, friendlyUrl, serviceContext);
			layout.setThemeId(theme);
			layout.setColorSchemeId(colorSchemeId);

			layout = layoutLocalService.updateLayout(layout);

			updateIfExists = true;
		}

		if ((layout != null) && updateIfExists) {
			if (group.isStagingGroup()) {
				stageLayoutUrls.add((Boolean.TRUE.equals(private_) ? PropsUtil
						.get(PropsKeys.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING) : PropsUtil
						.get(PropsKeys.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING))
						+ group.getFriendlyURL() + layout.getFriendlyURL());
			}

			// layout = updateTypeSettings(layout, log, addTypeSettings, group,
			// groupName, layoutTemplate, column1Portlets, column2Portlets,
			// column3Portlets,
			// column4Portlets, column5Portlets, column6Portlets,
			// column7Portlets, column8Portlets, column9Portlets);
			layout = updateTypeSettings(companyId, layout, log, addTypeSettings, group, groupName, layoutTemplate,
					columnPortlets);
		}

		// handle custom fields
		if ((updateIfExists || alwaysUpdateMetadata)) {
			if (layout != null) {
				if (customFields.size() > 0) {
					for (Entry<String, String> entry : customFields.entrySet()) {
						String att = entry.getKey();
						String value = entry.getValue();

						if (StringUtils.isNotBlank(att) && layout.getExpandoBridge().hasAttribute(att)) {
							CustomFieldDataUtil.setCustomFieldValue(layout.getExpandoBridge(), att, value);
						}
					}

					layout = layoutLocalService.updateLayout(layout);
				}
			} else {
				log.add("Layout '" + name + "' does not exist for " + getDisplayName(group));
			}
		}

		return layout;
	}

	protected long getParentLayoutId(Group group, String parentFriendlyUrl, boolean private_) throws Exception {
		long parentLayoutId = LayoutConstants.DEFAULT_PARENT_LAYOUT_ID;

		// lookup the parent layout ID
		if (parentFriendlyUrl != null) {
			Layout parentLayout = null;

			// search by parent friendly url
			try {
				parentLayout = layoutLocalService.getFriendlyURLLayout(group.getGroupId(), private_, parentFriendlyUrl);
				parentLayoutId = parentLayout.getLayoutId();
			} catch (NoSuchLayoutException nse) {
				throw new Exception("Parent layout '" + parentFriendlyUrl + "' not found for " + getDisplayName(group)
						+ ", parent not set");
			}
		}

		return parentLayoutId;
	}

	// protected Layout updateTypeSettings(Layout layout, ImportResults log,
	// String addTypeSettings, Group group, String groupName, String
	// layoutTemplate, String column1Portlets, String column2Portlets, String
	// column3Portlets,
	// String column4Portlets, String column5Portlets, String column6Portlets,
	// String column7Portlets, String column8Portlets, String column9Portlets)
	// throws Exception {
	// UnicodeProperties typeSettingsProperties =
	// layout.getTypeSettingsProperties();
	protected Layout updateTypeSettings(long companyId, Layout layout, ImportResults log, String addTypeSettings,
			Group group, String groupName, String layoutTemplate, List<String[]> columnPortlets) throws Exception {
		UnicodeProperties typeSettingsProperties = layout.getTypeSettingsProperties();

		if (StringUtils.isNotBlank(addTypeSettings)) {
			// merge with existing properties
			UnicodeProperties addProperties = new UnicodeProperties();
			addProperties.fastLoad(addTypeSettings);

			typeSettingsProperties.putAll(addProperties);
		}

		LinkedHashMap<String, String[]> webContentNames = new LinkedHashMap<String, String[]>();

		typeSettingsProperties.setProperty("layout-template-id", layoutTemplate);

		if (CollectionUtils.isNotEmpty(columnPortlets)) {
			for (String[] columnArray : columnPortlets) {
				if ((columnArray[1] != null) && (columnArray[1].length() > 0)) {
					typeSettingsProperties.setProperty("column-" + columnArray[0],
							addColumnPortlets(columnArray[1], webContentNames, group.getName()));
				}
			}
		}

		// if (column1Portlets != null && column1Portlets.length() > 0) {
		// typeSettingsProperties.setProperty("column-1",
		// addColumnPortlets(column1Portlets, webContentNames,
		// group.getName()));
		// }
		//
		// if (column2Portlets != null && column2Portlets.length() > 0) {
		// typeSettingsProperties.setProperty("column-2",
		// addColumnPortlets(column2Portlets, webContentNames,
		// group.getName()));
		// }
		//
		// if (column3Portlets != null && column3Portlets.length() > 0) {
		// typeSettingsProperties.setProperty("column-3",
		// addColumnPortlets(column3Portlets, webContentNames,
		// group.getName()));
		// }
		//
		// if (column4Portlets != null && column4Portlets.length() > 0) {
		// typeSettingsProperties.setProperty("column-4",
		// addColumnPortlets(column4Portlets, webContentNames,
		// group.getName()));
		// }
		//
		// if (column5Portlets != null && column5Portlets.length() > 0) {
		// typeSettingsProperties.setProperty("column-5",
		// addColumnPortlets(column5Portlets, webContentNames,
		// group.getName()));
		// }
		//
		// if (column6Portlets != null && column6Portlets.length() > 0) {
		// typeSettingsProperties.setProperty("column-6",
		// addColumnPortlets(column6Portlets, webContentNames,
		// group.getName()));
		// }
		//
		// if (column7Portlets != null && column7Portlets.length() > 0) {
		// typeSettingsProperties.setProperty("column-7",
		// addColumnPortlets(column7Portlets, webContentNames,
		// group.getName()));
		// }
		//
		// if (column8Portlets != null && column8Portlets.length() > 0) {
		// typeSettingsProperties.setProperty("column-8",
		// addColumnPortlets(column8Portlets, webContentNames,
		// group.getName()));
		// }
		//
		// if (column9Portlets != null && column9Portlets.length() > 0) {
		// typeSettingsProperties.setProperty("column-9",
		// addColumnPortlets(column9Portlets, webContentNames,
		// group.getName()));
		// }

		// apply web content if specified
		for (Map.Entry<String, String[]> entries : webContentNames.entrySet()) {
			String portletId = entries.getKey();
			String[] contentArray = entries.getValue();
			String contentGroupName = contentArray[0];
			String structureId = contentArray[1];
			String contentName = contentArray[2];

			if (contentGroupName == null || contentGroupName.trim().isEmpty())
				contentGroupName = groupName;

			Group contentGroup = group;
			if (!groupName.equals(contentGroupName)) {
				contentGroup = getGroup(group.getCompanyId(), contentGroupName);
			}

			// get article
			JournalArticle article = null;
			try {
				String tmpArticleId = "";
				if (StringUtils.isNotBlank(contentName)) {
					tmpArticleId = contentName.toUpperCase();
				}
				article = journalArticleLocalService.getArticle(contentGroup.getGroupId(), tmpArticleId);
			} catch (NoSuchArticleException nsa) {
				try {
					String articleURL = getArticleURL(contentName);

					article = journalArticleLocalService.getArticleByUrlTitle(contentGroup.getGroupId(), articleURL);
				} catch (NoSuchArticleException nsa2) {
					// ignore
					log.add(nsa2.getMessage());
				}
			}

			if (article == null) {
				log.add("Article '" + contentName + "' not found for layout web content");
			} else {
				JournalStructure structure = getStructure(structureId, contentGroup, companyId);

				setWebContentArticle(layout.getPlid(), portletId, article, structure, contentGroup);
				updateJournalContentSearch(layout, portletId, article.getArticleId());
			}
		}

		layout = updateLayout(layout, layout.getTypeSettings());
		return layout;
	}

	private JournalContentSearch updateJournalContentSearch(Layout layout, String portletId, String articleId)
			throws SystemException {
		long id = CounterLocalServiceUtil.increment();
		JournalContentSearch contentSearch = JournalContentSearchLocalServiceUtil.createJournalContentSearch(id);
		contentSearch.setCompanyId(layout.getCompanyId());
		contentSearch.setGroupId(layout.getGroupId());
		contentSearch.setPrivateLayout(layout.isPrivateLayout());
		contentSearch.setLayoutId(layout.getLayoutId());
		contentSearch.setPortletId(portletId);
		contentSearch.setArticleId(articleId);
		return JournalContentSearchLocalServiceUtil.updateJournalContentSearch(contentSearch);
	}

	protected String addColumnPortlets(String columnPortlets, LinkedHashMap<String, String[]> webContentNames,
			String defaultGroup) {
		StringBuilder buf = new StringBuilder();

		StringTokenizer tk = new StringTokenizer(columnPortlets, "|");
		while (tk.hasMoreTokens()) {
			String token = tk.nextToken().trim();

			buf.append(processInstanceable(token, webContentNames, defaultGroup));
			buf.append(",");
		}

		return buf.toString();
	}

	protected String processInstanceable(String inputText, LinkedHashMap<String, String[]> webContentNames,
			String defaultGroup) {
		Random random = new Random();

		// check for webcontent spec
		boolean wcMatched = false;
		Matcher wcMatcher = Pattern.compile("56\\[\\[(.*)\\]\\[(.*)\\](.+)\\]").matcher(inputText);
		String groupName = null;
		String structureId = null;
		String contentName = null;

		if (wcMatcher.matches()) {
			groupName = wcMatcher.group(1);
			structureId = wcMatcher.group(2);
			contentName = wcMatcher.group(3);
			wcMatched = true;
		} else {
			wcMatcher = Pattern.compile("56\\[\\[(.*)\\](.+)\\]").matcher(inputText);

			if (wcMatcher.matches()) {
				groupName = wcMatcher.group(1);
				contentName = wcMatcher.group(2);

				wcMatched = true;
			} else {
				wcMatcher = Pattern.compile("56\\[(.+)\\]").matcher(inputText);

				if (wcMatcher.matches()) {
					groupName = defaultGroup;
					contentName = wcMatcher.group(1);

					wcMatched = true;
				}
			}
		}

		if (wcMatched) {
			String[] contentArray = { groupName, structureId, contentName };

			String instanceId = "56_INSTANCE_" + random.nextInt(10) + random.nextInt(10) + random.nextInt(10)
					+ random.nextInt(10);

			// check that the content is defined

			webContentNames.put(instanceId, contentArray);

			return instanceId;
		} else {
			boolean instanceable = true;
			String text = inputText;

			if (text.startsWith("NOINST_")) {
				instanceable = false;
				text = inputText.substring("NOINST_".length());
			}

			// add portlet names from text
			String portletName = "NOMATCH";
			int index = text.indexOf("_WAR_");
			if (index != -1) {
				portletName = text.trim();
			}

			String[] instanceablePortletIds = { "56", "71", "73", "85" };

			for (String portletId : instanceablePortletIds) {
				StringBuffer result = new StringBuffer();

				// search for portlet ID with word boundary
				Matcher matcher = Pattern.compile("\\b" + portletId + "\\b").matcher(text);

				while (matcher.find() && instanceable) {
					// generate random 4 digit number
					String replacement = portletId + "_INSTANCE_" + random.nextInt(10) + random.nextInt(10)
							+ random.nextInt(10) + random.nextInt(10);

					matcher.appendReplacement(result, replacement);
				}

				matcher.appendTail(result);
				text = result.toString();
			}

			return text;
		}
	}

	protected Layout updateLayout(Layout layout, String typeSettings) throws Exception {
		return layoutLocalService.updateLayout(layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
				typeSettings);
	}

	protected Layout updateLayout(long plid, String name, String description, boolean privateLayout, boolean hidden,
			long parentLayoutId, String themeId, String colorSchemeId, String layoutTemplate) throws Exception {

		Layout layout = layoutLocalService.getLayout(plid);
		layout.setName(name, Locale.getDefault());
		layout.setDescription(description, Locale.getDefault());
		layout.setPrivateLayout(privateLayout);
		layout.setHidden(hidden);
		layout.setThemeId(themeId);
		layout.setColorSchemeId(colorSchemeId);
		layout.setParentLayoutId(parentLayoutId);

		layout.getTypeSettingsProperties().setProperty("layout-template-id", layoutTemplate);

		layout = layoutLocalService.updateLayout(layout);

		// update categories?
		// layoutLocalService.updateLayout(groupId, privateLayout, layoutId,
		// parentLayoutId, nameMap, titleMap, descriptionMap, keywordsMap,
		// robotsMap, type, hidden, friendlyURL, iconImage, iconBytes,
		// serviceContext);

		return layout;
	}

	protected void deleteAllPortlets(long plid, long userId) throws Exception {
		Layout layout = layoutLocalService.getLayout(plid);
		LayoutTypePortlet layoutTypePortlet = (LayoutTypePortlet) layout.getLayoutType();
		List<String> portletIds = layoutTypePortlet.getPortletIds();

		for (String portletId : portletIds) {
			if (layoutTypePortlet.hasPortletId(portletId)) {
				layoutTypePortlet.removePortletId(userId, portletId);
			}
		}

		// from UpdateLayoutAction
		layoutTypePortlet.resetModes();
		layoutTypePortlet.resetStates();

		layout = layoutLocalService.updateLayout(layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
				layout.getTypeSettings());

		for (String portletId : portletIds) {
			String rootPortletId = PortletConstants.getRootPortletId(portletId);

			resourceLocalService.deleteResource(layout.getCompanyId(), rootPortletId,
					ResourceConstants.SCOPE_INDIVIDUAL,
					PortletPermissionUtil.getPrimaryKey(layout.getPlid(), portletId));
		}
	}

	public JournalArticle createJournalArticle(User user, ImportResults log, Group group, String articleId,
			String name, String type, String description, long[] categoryIds, String content, String structureId,
			String templateId, Date displayDate, String displayPageFriendlyUrl, long[] structureCategoryIds,
			Map<String, String> articleReplaceMap, Map<String, JournalArticle> articleHistoryMap, boolean updateIfExists)
			throws Exception {
		log.add("Create web content '" + name + "' for " + getDisplayName(group));

		long classNameId = 0;
		long classPK = 0;
		boolean autoArticleId = true;

		boolean smallImage = false;
		String smallImageURL = null;
		File smallImageFile = null;
		Map<String, byte[]> images = null;
		String articleURL = getArticleURL(name);
		ServiceContext serviceContext = new ServiceContext();
		// fix GroupNotFound exception
		serviceContext.setScopeGroupId(group.getGroupId());
		serviceContext.setAddGuestPermissions(true);
		serviceContext.setAssetCategoryIds(categoryIds);
		serviceContext.setUserId(user.getUserId());
		String languageId = LanguageUtil.getLanguageId(LocaleUtil.getDefault());

		if (articleId != null && articleId.length() > 0) {
			autoArticleId = false;
		} else {
			articleId = "";
		}

		// generate content using TemplateNodeList
		if (StringUtils.isNotBlank(structureId)) {
			JournalArticle article = JournalArticleLocalServiceUtil.createJournalArticle(0);
			article.setContent(content);
			article.setArticleId(articleId);

			List<TemplateNode> nodes = JournalArticleDataUtil.getJournalDataNodeList(article);

			List<TemplateNode> finalNodes = new ArrayList<TemplateNode>();

			List<Long> structureCategoryIdsList = new ArrayList<Long>();
			if ((structureCategoryIds != null) && (structureCategoryIds.length > 0)) {
				for (long id : structureCategoryIds) {
					structureCategoryIdsList.add(id);
				}
			}

			// added for missing siblings adding.
			for (TemplateNode node : nodes) {
				finalNodes.add(doReplacement(group, node, structureCategoryIdsList, articleReplaceMap,
						articleHistoryMap, this.IS_NOT_FROM_SIBLING));
			}

			content = JournalArticleDataUtil.getContentFromNodes(finalNodes);
		}

		// // do a search and replace for articleIds
		// if ((articleReplaceMap != null) && (articleReplaceMap.size() > 0)) {
		// for (Entry<String, String> entry : articleReplaceMap.entrySet()) {
		// String replaceArticleId = entry.getKey();
		// String replaceTitle = entry.getValue();
		//
		// // TODO generate content using TemplateNodeList
		// if (StringUtils.isNotBlank(structureId)) {
		// JournalArticle article =
		// JournalArticleLocalServiceUtil.createJournalArticle(0);
		// article.setContent(content);
		// article.setArticleId(articleId);
		//
		// List<TemplateNode> nodes =
		// JournalArticleDataUtil.getJournalDataNodeList(article);
		//
		// List<TemplateNode> finalNodes = new ArrayList<TemplateNode>();
		//
		// for (TemplateNode node : nodes) {
		// finalNodes.add(doReplacement(group, node, replaceArticleId,
		// replaceTitle, articleHistoryMap));
		// }
		//
		// content = JournalArticleDataUtil.getContentFromNodes(finalNodes);
		// }
		//
		// // if (content.indexOf("\"articleid\":\"" + replaceArticleId +
		// // "\"") != -1) {
		// // if ((articleHistoryMap != null) && (articleHistoryMap.size()
		// // > 0)) {
		// // String newArticleId = articleHistoryMap.get(replaceTitle);
		// //
		// // if (StringUtils.isNotBlank(newArticleId)) {
		// // // now do replace
		// // content = content.replaceAll("\"articleid\":\"" +
		// // replaceArticleId + "\"",
		// // "\"articleid\":\"" + newArticleId + "\"");
		// // }
		// // }
		// // }
		// }
		// }

		String title = name;

		if (structureId == null && templateId == null) {
			// content="<?xml version='1.0' encoding='UTF-8'?><root available-locales=\"en_US\" default-locale=\"en_US\"><static-content language-id=\"en_US\"><![CDATA["+
			// content +"]]></static-content></root>";
			content = LocalizationUtil.updateLocalization(StringPool.BLANK, "static-content", content, languageId,
					languageId, true, true);
		}

		// now scrub it
		content = format(user, group.getGroupId(), articleId, 1, false, content, structureId, images);

		if (type == null || type.isEmpty()) {
			type = "general";
		}

		Calendar cal = Calendar.getInstance();

		// IS display date set?
		if (displayDate != null) {
			cal.setTime(displayDate);
		}

		int displayDateMonth = cal.get(Calendar.MONTH);
		int displayDateDay = cal.get(Calendar.DAY_OF_MONTH);
		int displayDateYear = cal.get(Calendar.YEAR);
		int displayDateHour = cal.get(Calendar.HOUR_OF_DAY);
		int displayDateMinute = cal.get(Calendar.MINUTE);
		int expirationDateMonth = 0;
		int expirationDateDay = 0;
		int expirationDateYear = 0;
		int expirationDateHour = 0;
		int expirationDateMinute = 0;
		boolean neverExpire = true;
		int reviewDateMonth = 0;
		int reviewDateDay = 0;
		int reviewDateYear = 0;
		int reviewDateHour = 0;
		int reviewDateMinute = 0;
		boolean neverReview = true;
		boolean indexable = true;

		// get the display page friendly URL
		String layoutUuid = null;

		if (displayPageFriendlyUrl != null && !displayPageFriendlyUrl.isEmpty()) {
			for (Layout layout : layoutLocalService.getLayouts(group.getGroupId(), false)) {
				if (layout.getFriendlyURL().equals(displayPageFriendlyUrl)) {
					layoutUuid = layout.getUuid();
					break;
				}
			}

			// not found in public, search private pages
			if (layoutUuid == null) {
				for (Layout layout : layoutLocalService.getLayouts(group.getGroupId(), true)) {
					if (layout.getFriendlyURL().equals(displayPageFriendlyUrl)) {
						layoutUuid = layout.getUuid();
						break;
					}
				}
			}

			if (layoutUuid == null) {
				throw new Exception("Display Page '" + displayPageFriendlyUrl + "' not found in "
						+ getDisplayName(group));
			}
		}

		try {
			// check if article already exists
			JournalArticle existingArticle = null;
			if (StringUtils.isNotBlank(articleId)) {
				String tmpArticleId = "";
				if (StringUtils.isNotBlank(articleId)) {
					tmpArticleId = articleId.toUpperCase();
				}

				existingArticle = journalArticleLocalService.getArticle(group.getGroupId(), tmpArticleId);
			} else {
				existingArticle = journalArticleLocalService.getArticleByUrlTitle(group.getGroupId(), articleURL);
			}

			if (updateIfExists) {
				// check if content changed
				boolean contentChanged = !existingArticle.getContent().equals(content);

				String msgStart = "JournalArticle with urlTitle=" + articleURL + " already exists ... ";

				if (contentChanged) {
					log.add(msgStart + "updating");

					// update the content
					existingArticle = journalArticleLocalService.updateContent(group.getGroupId(),
							existingArticle.getArticleId(), existingArticle.getVersion(), content);
				} else {
					log.add(msgStart + "leaving as is");
				}

				// display page change
				if ((layoutUuid != null && !layoutUuid.equals(existingArticle.getLayoutUuid()))
						|| (layoutUuid == null && existingArticle.getLayoutUuid() != null)) {
					// update layout UUID
					existingArticle.setLayoutUuid(layoutUuid);
					existingArticle = journalArticleLocalService.updateJournalArticle(existingArticle);
				}
			} else {
				log.add("JournalArticle with urlTitle '" + articleURL + "' already exists");
			}

			return existingArticle;
		} catch (NoSuchArticleException nsa) {
			// ignore
		}

		return journalArticleLocalService.addArticle(user.getUserId(), group.getGroupId(), classNameId, classPK,
				articleId, autoArticleId, 1, ImportUtil.toMap(title), ImportUtil.toMap(description), content, type,
				structureId, templateId, layoutUuid, displayDateMonth, displayDateDay, displayDateYear,
				displayDateHour, displayDateMinute, expirationDateMonth, expirationDateDay, expirationDateYear,
				expirationDateHour, expirationDateMinute, neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear,
				reviewDateHour, reviewDateMinute, neverReview, indexable, smallImage, smallImageURL, smallImageFile,
				images, articleURL, serviceContext);
	}

	// copied from com.liferay.portlet.journal.util.JournalUtil.getUrlTitle()
	private static final char[] _URL_TITLE_REPLACE_CHARS = new char[] { '.', '/' };

	protected String getArticleURL(String title) {
		title = title.trim().toLowerCase();

		title = FriendlyURLNormalizerUtil.normalize(title, _URL_TITLE_REPLACE_CHARS);

		title = ModelHintsUtil.trimString(JournalArticle.class.getName(), "urlTitle", title);

		return title;
	}

	protected TemplateNode doReplacement(Group group, TemplateNode node, List<Long> structureCategoryIds,
			Map<String, String> articleReplaceMap, Map<String, JournalArticle> articleHistoryMap, boolean isFromSibling) throws Exception {
		TemplateNode finalNode = null;

		if (node != null) {
			String data = node.getData();

			// get type
			String type = node.getType();
			if (type.equalsIgnoreCase("collection-picker")) {
				CollectionDataBean dataBean = CollectionDataUtil.getCollectionDataFromJSON(null, data);
				List<CollectionEntryBean> entries = dataBean.getDataCollection();
				if (CollectionUtils.isNotEmpty(entries)) {
					for (CollectionEntryBean entry : entries) {
						String replaceTitle = articleReplaceMap.get(entry.getArticleid());

						if (StringUtils.isNotBlank(replaceTitle)) {
							if ((articleHistoryMap != null) && (articleHistoryMap.size() > 0)) {
								JournalArticle newArticle = articleHistoryMap.get(entry.getType() + "_" + replaceTitle);
								if (newArticle != null) {
									String newArticleId = newArticle.getArticleId();

									if (StringUtils.isNotBlank(newArticleId)) {
										entry.setId(newArticle.getId());
										entry.setArticleid(newArticle.getArticleId());
										entry.setName(newArticle.getTitleCurrentValue());
										entry.setUrltitle(newArticle.getUrlTitle());
										entry.setDescription(newArticle.getDescriptionCurrentValue());
										entry.setGroupid(newArticle.getGroupId());
										entry.setStructureid(newArticle.getStructureId());
										entry.setTemplateid(newArticle.getTemplateId());
										entry.setType(newArticle.getType());
										entry.setStatus(newArticle.getStatus());
										entry.setCreatedate(newArticle.getCreateDate());
										entry.setModifieddate(newArticle.getModifiedDate());
										entry.setStatusdate(newArticle.getStatusDate());
										entry.setCreatedby(newArticle.getUserId());
										entry.setVersion(newArticle.getVersion());

										entry.setGroupname(group.getDescriptiveName());
									}
								}
							}
						}
					}
				}

				data = dataBean.toJSON();
			} else if (type.equalsIgnoreCase("category-select")) {
				if (CollectionUtils.isNotEmpty(structureCategoryIds)) {
					Iterator<Long> it = structureCategoryIds.iterator();
					Long structureCategoryId = it.next();
					if (structureCategoryId != null) {
						data = structureCategoryId.toString();
						it.remove();
					}
				}
			} else if (type.equalsIgnoreCase("dynamic-data-list")) {
				// TODO
			} else if (type.equalsIgnoreCase("document-library")) {
				// TODO
			}

			finalNode = new TemplateNode(null, node.getName(), data, type);

			// add options
			finalNode.appendOptions(node.getOptions());

			if (CollectionUtils.isNotEmpty(node.getChildren())) {
				List<TemplateNode> finalChildren = new ArrayList<TemplateNode>();
				for (TemplateNode childNode : node.getChildren()) {
					finalChildren.add(doReplacement(group, childNode, structureCategoryIds, articleReplaceMap,
							articleHistoryMap, this.IS_NOT_FROM_SIBLING));
				}

				finalNode.appendChildren(finalChildren);
			}

			// Added isFromSibling
			// If isFromSibling = true, do not need to go deeper, will result in StackOverFlowError.
			if (CollectionUtils.isNotEmpty(node.getSiblings()) && node.getSiblings().size() > 1 && !isFromSibling) {
				for (TemplateNode sibling : node.getSiblings()) {
					finalNode.appendSibling(doReplacement(group, sibling, structureCategoryIds, articleReplaceMap,
							articleHistoryMap, this.IS_FROM_SIBLING));
				}
			}
		}

		return finalNode;
	}

	protected void setWebContentArticle(long plid, String portletId, JournalArticle article,
			JournalStructure structure, Group group) throws Exception {
		List<PortletPreferences> prefList = portletPreferencesLocalService.getPortletPreferences(plid, portletId);

		Layout layout = layoutLocalService.getLayout(plid);
		long companyId = layout.getCompanyId();

		if (prefList.isEmpty()) {
			long ownerId = 0;
			int ownerType = PortletKeys.PREFS_OWNER_TYPE_LAYOUT;

			StringBuilder buf = new StringBuilder();
			buf.append("<portlet-preferences>");
			buf.append("<preference><name>articleId</name><value>");
			buf.append(article.getArticleId());
			buf.append("</value></preference>");
			buf.append("<preference><name>groupId</name><value>");
			buf.append(group.getGroupId());
			buf.append("</value></preference>");
			buf.append("<preference><name>enableRelatedAssets</name><value>");
			buf.append(false);
			buf.append("</value></preference>");
			if (structure != null) {
				buf.append("<preference><name>structureId</name><value>");
				buf.append(structure.getStructureId());
				buf.append("</value></preference>");
				buf.append("<preference><name>portletSetupTitle_en_US</name><value>");
				buf.append(structure.getNameCurrentValue());
				buf.append("</value></preference>");
				buf.append("<preference><name>portletSetupUseCustomTitle</name><value>");
				buf.append(true);
				buf.append("</value></preference>");
				buf.append("<preference><name>enableViewCountIncrement</name><value>");
				buf.append(false);
				buf.append("</value></preference>");
			}
			buf.append("</portlet-preferences>");

			// String prefString =
			// "<portlet-preferences><preference><name>articleId</name><value>"+articleId+"</value></preference>"+
			// "<preference><name>groupId</name><value>"+groupId+"</value></preference>"+
			// "</portlet-preferences>";

			String prefString = buf.toString();

			// create new preference
			portletPreferencesLocalService.addPortletPreferences(companyId, ownerId, ownerType, plid, portletId, null,
					prefString);
		} else {
			for (PortletPreferences pref : prefList) {
				javax.portlet.PortletPreferences jpPrefs = portletPreferencesLocalService.getPreferences(companyId,
						pref.getOwnerId(), pref.getOwnerType(), plid, portletId);

				jpPrefs.setValue("articleId", article.getArticleId());
				jpPrefs.setValue("groupId", Long.toString(group.getGroupId()));
				jpPrefs.setValue("enableRelatedAssets", "false");
				if (structure != null) {
					jpPrefs.setValue("structureId", structure.getStructureId());
					jpPrefs.setValue("portletSetupTitle_en_US", structure.getNameCurrentValue());
					jpPrefs.setValue("portletSetupUseCustomTitle", "true");
				}

				jpPrefs.store();
			}
		}
	}

	protected JournalStructure getStructure(String structureId, Group group, long companyId) {
		JournalStructure structure = null;

		if (StringUtils.isNotBlank(structureId)) {
			// get Structure
			try {
				// local staging groupId
				Group siteGroup = GroupUtil.getContentGroup(group);
				structure = JournalStructureLocalServiceUtil.getStructure(siteGroup.getGroupId(), structureId);
			} catch (Exception e) {
				// now try from Global
				try {
					Group globalGroup = GroupLocalServiceUtil.getGroup(companyId, Long.toString(companyId));
					if (globalGroup != null) {
						structure = JournalStructureLocalServiceUtil
								.getStructure(globalGroup.getGroupId(), structureId);
					}
				} catch (Exception ex) {
					// do nothing
				}
			}
		}

		return structure;
	}

	/***********
	 * Taken from Liferay JournalArticleLocalServiceImpl
	 ***********/
	protected String format(User user, long groupId, String articleId, double version, boolean incrementVersion,
			String content, String structureId, Map<String, byte[]> images) throws PortalException, SystemException {

		Document document = null;

		try {
			document = SAXReaderUtil.read(content);

			Element rootElement = document.getRootElement();

			if (Validator.isNotNull(structureId)) {
				format(user, groupId, articleId, version, incrementVersion, rootElement, images);
			} else {
				List<Element> staticContentElements = rootElement.elements("static-content");

				for (Element staticContentElement : staticContentElements) {
					String staticContent = staticContentElement.getText();

					staticContent = SanitizerUtil.sanitize(user.getCompanyId(), groupId, user.getUserId(),
							JournalArticle.class.getName(), 0, ContentTypes.TEXT_HTML, staticContent);

					staticContentElement.setText(staticContent);
				}
			}

			content = DDMXMLUtil.formatXML(document);
		} catch (DocumentException de) {
			_log.error(de);
		} catch (IOException ioe) {
			_log.error(ioe);
		}

		content = HtmlUtil.replaceMsWordCharacters(content);

		return content;
	}

	protected void format(User user, long groupId, String articleId, double version, boolean incrementVersion,
			Element root, Map<String, byte[]> images) throws PortalException, SystemException {

		for (Element element : root.elements()) {
			String elInstanceId = element.attributeValue("instance-id", StringPool.BLANK);
			String elName = element.attributeValue("name", StringPool.BLANK);
			String elType = element.attributeValue("type", StringPool.BLANK);

			if (elType.equals("image")) {
				formatImage(groupId, articleId, version, incrementVersion, element, elInstanceId, elName, images);
			} else if (elType.equals("text_area") || elType.equals("text") || elType.equals("text_box")) {

				List<Element> dynamicContentElements = element.elements("dynamic-content");

				for (Element dynamicContentElement : dynamicContentElements) {
					String dynamicContent = dynamicContentElement.getText();

					if (Validator.isNotNull(dynamicContent)) {
						dynamicContent = SanitizerUtil.sanitize(user.getCompanyId(), groupId, user.getUserId(),
								JournalArticle.class.getName(), 0, ContentTypes.TEXT_HTML, dynamicContent);

						dynamicContentElement.setText(dynamicContent);
					}
				}
			}

			format(user, groupId, articleId, version, incrementVersion, element, images);
		}
	}

	protected void formatImage(long groupId, String articleId, double version, boolean incrementVersion, Element el,
			String elInstanceId, String elName, Map<String, byte[]> images) throws PortalException, SystemException {

		List<Element> imageContents = el.elements("dynamic-content");

		for (Element dynamicContent : imageContents) {
			String elLanguage = dynamicContent.attributeValue("language-id", StringPool.BLANK);

			if (!elLanguage.equals(StringPool.BLANK)) {
				elLanguage = "_" + elLanguage;
			}

			long imageId = JournalArticleImageLocalServiceUtil.getArticleImageId(groupId, articleId, version,
					elInstanceId, elName, elLanguage);

			double oldVersion = MathUtil.format(version - 0.1, 1, 1);

			long oldImageId = 0;

			if ((oldVersion >= 1) && incrementVersion) {
				oldImageId = JournalArticleImageLocalServiceUtil.getArticleImageId(groupId, articleId, oldVersion,
						elInstanceId, elName, elLanguage);
			}

			String elContent = "/image/journal/article?img_id=" + imageId + "&t="
					+ WebServerServletTokenUtil.getToken(imageId);

			if (dynamicContent.getText().equals("delete")) {
				dynamicContent.setText(StringPool.BLANK);

				ImageLocalServiceUtil.deleteImage(imageId);

				String defaultElLanguage = "";

				if (!Validator.isNotNull(elLanguage)) {
					defaultElLanguage = "_" + LocaleUtil.toLanguageId(LocaleUtil.getDefault());
				}

				long defaultImageId = JournalArticleImageLocalServiceUtil.getArticleImageId(groupId, articleId,
						version, elInstanceId, elName, defaultElLanguage);

				ImageLocalServiceUtil.deleteImage(defaultImageId);

				continue;
			}

			byte[] bytes = images.get(elInstanceId + "_" + elName + elLanguage);

			if ((bytes != null) && (bytes.length > 0)) {
				dynamicContent.setText(elContent);
				dynamicContent.addAttribute("id", String.valueOf(imageId));

				ImageLocalServiceUtil.updateImage(imageId, bytes);

				continue;
			}

			if ((version > JournalArticleConstants.VERSION_DEFAULT) && (incrementVersion)) {

				Image oldImage = null;

				if (oldImageId > 0) {
					oldImage = ImageLocalServiceUtil.getImage(oldImageId);
				}

				if (oldImage != null) {
					dynamicContent.setText(elContent);
					dynamicContent.addAttribute("id", String.valueOf(imageId));

					bytes = oldImage.getTextObj();

					ImageLocalServiceUtil.updateImage(imageId, bytes);
				}

				continue;
			}

			Image image = ImageLocalServiceUtil.getImage(imageId);

			if (image != null) {
				dynamicContent.setText(elContent);
				dynamicContent.addAttribute("id", String.valueOf(imageId));

				continue;
			}

			long contentImageId = GetterUtil.getLong(HttpUtil.getParameter(dynamicContent.getText(), "img_id"));

			if (contentImageId <= 0) {
				contentImageId = GetterUtil.getLong(HttpUtil.getParameter(dynamicContent.getText(), "img_id", false));
			}

			if (contentImageId > 0) {
				image = ImageLocalServiceUtil.getImage(contentImageId);

				if (image != null) {
					dynamicContent.addAttribute("id", String.valueOf(contentImageId));

					continue;
				}
			}

			String defaultElLanguage = "";

			if (!Validator.isNotNull(elLanguage)) {
				defaultElLanguage = "_" + LocaleUtil.toLanguageId(LocaleUtil.getDefault());
			}

			long defaultImageId = JournalArticleImageLocalServiceUtil.getArticleImageId(groupId, articleId, version,
					elInstanceId, elName, defaultElLanguage);

			Image defaultImage = ImageLocalServiceUtil.getImage(defaultImageId);

			if (defaultImage != null) {
				dynamicContent.setText(elContent);
				dynamicContent.addAttribute("id", String.valueOf(defaultImageId));

				bytes = defaultImage.getTextObj();

				ImageLocalServiceUtil.updateImage(defaultImageId, bytes);

				continue;
			}

			if (Validator.isNotNull(elLanguage)) {
				dynamicContent.setText(StringPool.BLANK);
			}
		}
	}

	/***********
	 * End Copy from Liferay JournalArticleLocalServiceImpl
	 ***********/

	public JournalStructure createJournalStructure(User user, ImportResults log, Group group, String id,
			String parentId, String name, String description, long[] categoryIds, String xsd, boolean updateIfExists)
			throws Exception {
		log.add("Create structure '" + name + "' for " + getDisplayName(group));

		boolean autoStructureId = false;
		ServiceContext serviceContext = new ServiceContext();
		serviceContext.setAssetCategoryIds(categoryIds);
		serviceContext.setUserId(user.getUserId());

		try {
			// check if structure already exists
			JournalStructure existingStructure = journalStructureLocalService.getStructure(group.getGroupId(), id);

			String msgStart = "Structure with id=" + id + " already exists exists ... ";

			if (updateIfExists) {
				existingStructure = journalStructureLocalService.updateStructure(group.getGroupId(), id, parentId,
						ImportUtil.toMap(name), ImportUtil.toMap(description), xsd, serviceContext);
				log.add(msgStart + "updating");
			} else {
				log.add(msgStart + "leaving as is");
			}

			return existingStructure;
		} catch (com.liferay.portlet.journal.NoSuchStructureException nsa) {
			// ignore
		}

		return journalStructureLocalService.addStructure(user.getUserId(), group.getGroupId(), id, autoStructureId,
				parentId, ImportUtil.toMap(name), ImportUtil.toMap(description), xsd, serviceContext);
	}

	public JournalTemplate createJournalTemplate(User user, ImportResults log, Group group, String id,
			String structureId, String name, String description, long[] categoryIds, boolean cacheable,
			String langType, String script, boolean updateIfExists) throws Exception {
		log.add("Create template '" + name + "' for " + getDisplayName(group));

		boolean autoTemplateId = false;
		boolean formatXsl = false;
		boolean smallImage = false;
		String smallImageURL = null;
		File smallImageFile = null;
		ServiceContext serviceContext = new ServiceContext();
		serviceContext.setAssetCategoryIds(categoryIds);
		serviceContext.setUserId(user.getUserId());

		try {
			// check if template already exists
			JournalTemplate existingTemplate = journalTemplateLocalService.getTemplate(group.getGroupId(), id);

			String msgSta
ExcelImport——2013-03-14 11:01:12
package com.endplay.dataimport.util;

import com.endplay.dataimport.portlet.service.ImportLocalServiceUtil;
import com.endplay.util.excel.ExcelUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.model.Group;
import com.liferay.portal.model.GroupConstants;
import com.liferay.portal.model.Layout;
import com.liferay.portal.model.LayoutPrototype;
import com.liferay.portal.model.LayoutSetPrototype;
import com.liferay.portal.model.Organization;
import com.liferay.portal.model.Role;
import com.liferay.portal.model.RoleConstants;
import com.liferay.portal.model.User;
import com.liferay.portal.service.OrganizationLocalServiceUtil;
import com.liferay.portal.service.RoleLocalServiceUtil;
import com.liferay.portlet.asset.NoSuchVocabularyException;
import com.liferay.portlet.asset.model.AssetCategory;
import com.liferay.portlet.asset.model.AssetVocabulary;
import com.liferay.portlet.asset.service.AssetVocabularyLocalServiceUtil;
import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
import com.liferay.portlet.dynamicdatalists.model.DDLRecord;
import com.liferay.portlet.dynamicdatalists.model.DDLRecordSet;
import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
import com.liferay.portlet.expando.model.ExpandoColumn;
import com.liferay.portlet.expando.model.ExpandoColumnConstants;
import com.liferay.portlet.journal.model.JournalArticle;
import com.liferay.portlet.journal.model.JournalStructure;
import com.liferay.portlet.journal.model.JournalTemplate;

import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;

public class ExcelImport {
	protected final int ROW_HEADER = ExcelUtil.getSSRow(3);
	protected final int ROW_DATASTART = ExcelUtil.getSSRow(4);
	protected final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
	protected final String EXCEL_ROW = "EXCEL_ROW";
	protected final int NUM_COLUMNS = 20;

	protected User user;
	protected long companyId;
	protected ImportResults log;
	protected SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
	protected ArrayList<String> stageLayoutUrls = new ArrayList<String>();

	public ExcelImport(User user) {
		this.user = user;
		this.companyId = user.getCompanyId();

		log = new ImportResults(dateFormat);
	}

	public void processExcel(InputStream inputStream) throws Exception {
		try {
			Workbook wb = ExcelUtil.getWorkbook(inputStream);

			List<Properties> propertiesList;

			Map<String, String> articleReplaceMap = new HashMap<String, String>();

			propertiesList = ImportUtil.getProperties(wb, "Custom Fields", ROW_HEADER, ROW_DATASTART, dateFormat,
					EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createCustomFields(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "Article Replace", ROW_HEADER, ROW_DATASTART, dateFormat,
					EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createArticleReplace(properties, articleReplaceMap);
			}

			propertiesList = ImportUtil.getProperties(wb, "Organization", ROW_HEADER, ROW_DATASTART, dateFormat,
					EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createOrganization(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "Group", ROW_HEADER, ROW_DATASTART, dateFormat, EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createGroup(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "Role", ROW_HEADER, ROW_DATASTART, dateFormat, EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createRole(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "User", ROW_HEADER, ROW_DATASTART, dateFormat, EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createUser(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "Organization User Role", ROW_HEADER, ROW_DATASTART,
					dateFormat, EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createOrgUserRole(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "Category", ROW_HEADER, ROW_DATASTART, dateFormat, EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createCategory(properties);
			}

			propertiesList = ImportUtil
					.getProperties(wb, "Structure", ROW_HEADER, ROW_DATASTART, dateFormat, EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createJournalStructure(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "Template", ROW_HEADER, ROW_DATASTART, dateFormat, EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createJournalTemplate(properties);
			}

			Map<String, JournalArticle> articleHistoryMap = new HashMap<String, JournalArticle>();

			propertiesList = ImportUtil.getProperties(wb, "Web Content", ROW_HEADER, ROW_DATASTART, dateFormat,
					EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createJournalArticle(properties, articleReplaceMap, articleHistoryMap);
			}

			propertiesList = ImportUtil.getProperties(wb, "Page Template", ROW_HEADER, ROW_DATASTART, dateFormat,
					EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createPageTemplate(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "Site Template", ROW_HEADER, ROW_DATASTART, dateFormat,
					EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createSiteTemplate(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "Site Template Layout", ROW_HEADER, ROW_DATASTART,
					dateFormat, EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createSiteTemplateLayout(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "Page", ROW_HEADER, ROW_DATASTART, dateFormat, EXCEL_ROW,
					"Layout");
			for (Properties properties : propertiesList) {
				createLayout(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "Metadata Set", ROW_HEADER, ROW_DATASTART, dateFormat,
					EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createMetadataSet(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "Document Type", ROW_HEADER, ROW_DATASTART, dateFormat,
					EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createDocumentType(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "Data Definition", ROW_HEADER, ROW_DATASTART, dateFormat,
					EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createDataDefinition(properties);
			}

			propertiesList = ImportUtil
					.getProperties(wb, "Data List", ROW_HEADER, ROW_DATASTART, dateFormat, EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createDynamicDataList(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "Data List Record", ROW_HEADER, ROW_DATASTART, dateFormat,
					EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createDynamicDataListRecord(properties);
			}

			propertiesList = ImportUtil.getProperties(wb, "Resource Permission", ROW_HEADER, ROW_DATASTART, dateFormat,
					EXCEL_ROW);
			for (Properties properties : propertiesList) {
				createResourcePermissions(properties);
			}

			// list layouts that must be published to live manually
			if (!stageLayoutUrls.isEmpty()) {
				// TODO: PUBLISH TO LIVE
				/*
				 * URL serverUrl = new URL(url);
				 * 
				 * String prefix =
				 * serverUrl.getProtocol()+"://"+serverUrl.getHost(); if
				 * (serverUrl.getPort() > 0) { prefix +=
				 * ":"+serverUrl.getPort(); } prefix += "/";
				 */
				log.add("The following staged layouts must be manually published to live:");

				for (String url : stageLayoutUrls) {
					log.add("<a href=\""+url+"\">"+url+"</a>");
				}
			}
		} catch (Exception ex) {
			log.add(ex.toString());

			throw ex;
		}
	}

	public String getGroupProperty(Properties properties) {
		return ImportUtil.getProperty(properties, "Group", "Group Name");
	}

	public List<String> getLogEntries() {
		return log.getEntries();
	}

	protected boolean getUpdateIfExists(Properties properties) {
		String updateStr = properties.getProperty("Update If Exists");
		return updateStr != null && Boolean.parseBoolean(updateStr);
	}

	protected boolean getAlwaysUpdateMetadata(Properties properties) {
		String updateStr = properties.getProperty("Always Update Metadata");
		return updateStr != null && Boolean.parseBoolean(updateStr);
	}

	public Group createGroup(Properties properties) throws Exception {
		String name = properties.getProperty("Name");
		String description = properties.getProperty("Description");

		String typeName = properties.getProperty("Type");
		int type = GroupConstants.TYPE_SITE_PRIVATE;

		if (GroupConstants.TYPE_SITE_OPEN_LABEL.equalsIgnoreCase(typeName)) {
			type = GroupConstants.TYPE_SITE_OPEN;
		} else if (GroupConstants.TYPE_SITE_PRIVATE_LABEL.equalsIgnoreCase(typeName)) {
			type = GroupConstants.TYPE_SITE_PRIVATE;
		} else if (GroupConstants.TYPE_SITE_RESTRICTED_LABEL.equalsIgnoreCase(typeName)) {
			type = GroupConstants.TYPE_SITE_RESTRICTED;
		}

		String friendlyUrl = properties.getProperty("FriendlyUrl");
		Boolean staging = Boolean.parseBoolean(properties.getProperty("Staging"));
		String typeSettings = properties.getProperty("TypeSettings");

		String rowId = properties.getProperty(EXCEL_ROW);

		Group group = ImportLocalServiceUtil.createGroup(user, log, name, description, type, friendlyUrl, staging,
				typeSettings, rowId);

		return group;
	}

	protected void createArticleReplace(Properties properties, Map<String, String> articleReplaceMap) throws Exception {
		String articleId = properties.getProperty("ArticleId");
		String title = properties.getProperty("Title");

		articleReplaceMap.put(articleId, title);
	}

	protected Layout createLayout(Properties properties) throws Exception {
		String pageTemplate = properties.getProperty("Page Template");

		if (pageTemplate != null && !pageTemplate.isEmpty()) {
			// create layout using page template
			return createPageTemplateLayout(properties);
		} else {
			String groupName = getGroupProperty(properties);
			String name = properties.getProperty("Name");
			String description = properties.getProperty("Description");
			String friendlyUrl = properties.getProperty("Friendly URL");
			String type = properties.getProperty("Type");
			Boolean private_ = Boolean.parseBoolean(properties.getProperty("Private"));
			Boolean hidden = Boolean.parseBoolean(properties.getProperty("Hidden"));
			String parentFriendlyUrl = properties.getProperty("Parent Friendly URL");

			Map<String, String> customFields = getCustomFieldValues(properties);

			String theme = properties.getProperty("Theme");

			if (theme == null) {
				theme = "";
			}

			String colorScheme = ImportUtil.getProperty(properties, "Color Scheme", "ColorSchemeId");

			String typeSettings = properties.getProperty("TypeSettings");
			String layoutTemplate = properties.getProperty("Layout Template");

			List<String[]> columnPortlets = new ArrayList<String[]>();

			for (int i = 0; i < NUM_COLUMNS; i++) {
				String columnPortlet = properties.getProperty("Column" + i + " Portlets");
				if (StringUtils.isNotBlank(columnPortlet)) {
					String[] columnArray = new String[2];
					columnArray[0] = Integer.toString(i);
					columnArray[1] = columnPortlet;
					columnPortlets.add(columnArray);
				}
			}

			// String
			// column1Portlets=properties.getProperty("Column1 Portlets");
			// String
			// column2Portlets=properties.getProperty("Column2 Portlets");
			// String
			// column3Portlets=properties.getProperty("Column3 Portlets");
			// String
			// column4Portlets=properties.getProperty("Column4 Portlets");
			// String
			// column5Portlets=properties.getProperty("Column5 Portlets");
			// String
			// column6Portlets=properties.getProperty("Column6 Portlets");
			// String
			// column7Portlets=properties.getProperty("Column7 Portlets");
			// String
			// column8Portlets=properties.getProperty("Column8 Portlets");
			// String
			// column9Portlets=properties.getProperty("Column9 Portlets");
			// String
			// column10Portlets=properties.getProperty("Column10 Portlets");
			// String
			// column11Portlets=properties.getProperty("Column11 Portlets");
			// String
			// column12Portlets=properties.getProperty("Column12 Portlets");
			// String
			// column13Portlets=properties.getProperty("Column13 Portlets");
			// String
			// column14Portlets=properties.getProperty("Column14 Portlets");

			Group group = ImportLocalServiceUtil.getGroup(companyId, groupName);
			long[] categoryIds = getCategoryIds(properties, group.getGroupId());

			boolean updateIfExists = getUpdateIfExists(properties);

			boolean alwaysUpdateMetadata = getAlwaysUpdateMetadata(properties);

			// Layout layout = ImportLocalServiceUtil.createLayout(user, log,
			// stageLayoutUrls, groupName, name, description, friendlyUrl,
			// private_, hidden, parentFriendlyUrl, theme, colorScheme,
			// layoutTemplate, typeSettings, categoryIds,
			// column1Portlets, column2Portlets, column3Portlets,
			// column4Portlets, column5Portlets,
			// column6Portlets, column7Portlets, column8Portlets,
			// column9Portlets, updateIfExists);
			Layout layout = ImportLocalServiceUtil.createLayout(user, log, stageLayoutUrls, groupName, name,
					description, friendlyUrl, type, private_, hidden, parentFriendlyUrl, theme, colorScheme,
					layoutTemplate, typeSettings, categoryIds, columnPortlets, updateIfExists, alwaysUpdateMetadata,
					customFields);

			return layout;
		}
	}

	protected User createUser(Properties properties) throws Exception {
		String firstName = properties.getProperty("First Name");
		String middleName = properties.getProperty("Middle Name");
		String lastName = properties.getProperty("Last Name");
		String emailAddress = properties.getProperty("Email Address");
		String screenName = properties.getProperty("Screen Name");
		String password = properties.getProperty("Password");

		String facebookIdStr = properties.getProperty("Facebook ID");
		Long facebookId = (facebookIdStr == null) ? 0 : Long.parseLong(properties.getProperty("Facebook ID"));
		Boolean male = Boolean.parseBoolean(properties.getProperty("Male"));
		Boolean sendEmail = Boolean.parseBoolean(properties.getProperty("Send Email"));
		String groupList = properties.getProperty("Group Names");
		String orgList = properties.getProperty("Org Names");
		String roleList = properties.getProperty("Role Names");

		int birthdayYear = Integer.parseInt(properties.getProperty("Birthday Year"));
		int birthdayMonth = Integer.parseInt(properties.getProperty("Birthday Month #")) - 1;
		int birthdayDay = Integer.parseInt(properties.getProperty("Birthday Day"));

		Map<String, String> customFields = getCustomFieldValues(properties);

		// extract the groups & roles
		int i;

		long[] groupIds = null;
		if (StringUtils.isNotBlank(groupList)) {
			String[] groupNames = groupList.split("\\s*,\\s*");
			groupIds = new long[groupNames.length];
			i = 0;
			for (String groupName : groupNames) {
				Group group = ImportLocalServiceUtil.getGroup(companyId, groupName);

				groupIds[i++] = group.getGroupId();
			}
		}

		i = 0;
		long[] orgIds = null;
		if (StringUtils.isNotBlank(orgList)) {
			String[] orgNames = orgList.split("\\s*,\\s*");
			orgIds = new long[orgNames.length];
			i = 0;
			for (String orgName : orgNames) {
				Organization org = OrganizationLocalServiceUtil.getOrganization(companyId, orgName);

				orgIds[i++] = org.getOrganizationId();
			}
		}

		String[] roleNames = roleList.split("\\s*,\\s*");
		long[] roleIds = new long[roleNames.length];
		i = 0;
		for (String roleName : roleNames) {
			Role role = RoleLocalServiceUtil.getRole(companyId, roleName);

			roleIds[i++] = role.getRoleId();
		}

		boolean alwaysUpdateMetadata = getAlwaysUpdateMetadata(properties);

		User newUser = ImportLocalServiceUtil.createUser(user, log, firstName, middleName, lastName, screenName,
				emailAddress, password, facebookId, male, birthdayMonth, birthdayDay, birthdayYear, sendEmail,
				groupIds, orgIds, roleIds, customFields, alwaysUpdateMetadata);

		return newUser;
	}

	protected Role createRole(Properties properties) throws Exception {
		String name = properties.getProperty("Name");
		String description = properties.getProperty("Description");
		String type = properties.getProperty("Type");

		int typeId = 0;

		if (type.equalsIgnoreCase(RoleConstants.TYPE_ORGANIZATION_LABEL)) {
			typeId = RoleConstants.TYPE_ORGANIZATION;
		} else if (type.equalsIgnoreCase(RoleConstants.TYPE_SITE_LABEL)) {
			typeId = RoleConstants.TYPE_SITE;
		} else if (type.equalsIgnoreCase(RoleConstants.TYPE_REGULAR_LABEL)) {
			typeId = RoleConstants.TYPE_REGULAR;
		} else {
			throw new Exception("Unknown type " + type + " for Role=" + name);
		}

		String title = null;

		Role role = ImportLocalServiceUtil.createRole(user, log, name, title, description, typeId, companyId);

		return role;
	}

	protected DDMStructure createMetadataSet(Properties properties) throws Exception {
		String groupName = properties.getProperty("Group");

		// lookup the group/staging group by name
		Group group = ImportLocalServiceUtil.getGroup(companyId, groupName);

		String name = properties.getProperty("Name");
		String description = properties.getProperty("Description");
		String schema = properties.getProperty("Schema");

		String className = "com.liferay.portlet.documentlibrary.model.DLFileEntryMetadata";
		String type = "Metadata Set";

		boolean updateIfExists = getUpdateIfExists(properties);

		DDMStructure structure = ImportLocalServiceUtil.createDDMStructure(user, log, type, group, className, name,
				description, schema, updateIfExists);

		return structure;
	}

	protected DLFileEntryType createDocumentType(Properties properties) throws Exception {
		String groupName = getGroupProperty(properties);

		// lookup the group/staging group by name
		Group group = ImportLocalServiceUtil.getGroup(companyId, groupName);

		String name = properties.getProperty("Name");
		String description = properties.getProperty("Description");
		String schema = properties.getProperty("Schema");
		String structureKeyList = properties.getProperty("Metadata Sets");

		int i;

		String[] structureKeys = structureKeyList.split("\\s*,\\s*");
		long[] ddmStructureIds = new long[structureKeys.length];
		i = 0;
		for (String structureKey : structureKeys) {
			DDMStructure structure = DDMStructureLocalServiceUtil.getStructure(group.getGroupId(), structureKey);

			ddmStructureIds[i++] = structure.getStructureId();
		}

		DLFileEntryType docType = ImportLocalServiceUtil.createDocumentType(user, log, group, name, description,
				ddmStructureIds, schema);

		return docType;
	}

	protected JournalStructure createJournalStructure(Properties properties) throws Exception {
		String groupName = getGroupProperty(properties);

		// lookup the group/staging group by name
		Group group = ImportLocalServiceUtil.getGroup(companyId, groupName);

		String id = properties.getProperty("ID");
		String name = properties.getProperty("Name");
		String description = properties.getProperty("Description");
		String xsd = properties.getProperty("Schema");
		String parentId = properties.getProperty("Parent ID");

		long[] categoryIds = getCategoryIds(properties, group.getGroupId());

		boolean updateIfExists = getUpdateIfExists(properties);

		JournalStructure structure = ImportLocalServiceUtil.createJournalStructure(user, log, group, id, parentId,
				name, description, categoryIds, xsd, updateIfExists);

		return structure;
	}

	protected JournalTemplate createJournalTemplate(Properties properties) throws Exception {
		String groupName = getGroupProperty(properties);

		// lookup the group/staging group by name
		Group group = ImportLocalServiceUtil.getGroup(companyId, groupName);

		String id = properties.getProperty("ID");
		String structureId = properties.getProperty("Structure ID");
		String name = properties.getProperty("Name");
		String description = properties.getProperty("Description");
		String langType = properties.getProperty("Language");
		// String script = properties.getProperty("Script");

		long[] categoryIds = getCategoryIds(properties, group.getGroupId());

		boolean updateIfExists = getUpdateIfExists(properties);

		String cacheableStr = properties.getProperty("Cacheable");
		boolean cacheable = cacheableStr != null && Boolean.parseBoolean(cacheableStr);

		StringBuilder buf = new StringBuilder();

		String baseTxt = properties.getProperty("Script");
		if (StringUtils.isNotBlank(baseTxt)) {
			buf.append(baseTxt);
			buf.append("\n");
			buf.append("\n");
		}

		for (int i = 1; i <= NUM_COLUMNS; i++) {
			String txt = properties.getProperty("Script" + i);
			if (StringUtils.isNotBlank(txt)) {
				buf.append(txt);
				buf.append("\n");
				buf.append("\n");
			} else {
				break;
			}
		}

		String script = buf.toString();

		JournalTemplate template = ImportLocalServiceUtil.createJournalTemplate(user, log, group, id, structureId,
				name, description, categoryIds, cacheable, langType, script, updateIfExists);

		return template;
	}

	protected JournalArticle createJournalArticle(Properties properties, Map<String, String> articleReplaceMap,
			Map<String, JournalArticle> articleHistoryMap) throws Exception {
		boolean updateIfExists = getUpdateIfExists(properties);

		String groupName = getGroupProperty(properties);

		// lookup the group by name
		Group group = ImportLocalServiceUtil.getGroup(companyId, groupName);

		String articleId = properties.getProperty("Article ID");
		String name = properties.getProperty("Name");
		String type = properties.getProperty("Type");
		String description = properties.getProperty("Description");
		String content = properties.getProperty("HTML");
		String structureId = properties.getProperty("Structure ID");
		String templateId = properties.getProperty("Template ID");

		String displayPageFriendlyUrl = properties.getProperty("Display Page Friendly URL");

		String dateString = properties.getProperty("Display Date");

		Date displayDate = null;
		if (dateString != null && !dateString.isEmpty()) {
			displayDate = dateFormat.parse(dateString);
		}

		long[] categoryIds = getCategoryIds(properties, group.getGroupId());

		String structureCategoryList = properties.getProperty("Structure Categories");
		long[] structureCategoryIds = getCategoryIds(structureCategoryList, group.getGroupId());

		JournalArticle article = ImportLocalServiceUtil.createJournalArticle(user, log, group, articleId, name, type,
				description, categoryIds, content, structureId, templateId, displayDate, displayPageFriendlyUrl,
				structureCategoryIds, articleReplaceMap, articleHistoryMap, updateIfExists);

		articleHistoryMap.put(article.getType() + "_" + name, article);

		return article;
	}

	protected long[] getCategoryIds(Properties properties, long groupId) throws Exception {
		String categoryList = properties.getProperty("Categories");

		return getCategoryIds(categoryList, groupId);
	}

	protected long[] getCategoryIds(String categoryList, long groupId) throws Exception {
		long[] categoryIds = null;

		if (categoryList != null && !categoryList.isEmpty()) {
			String[] categoryNames = categoryList.split("\\s*,\\s*");
			categoryIds = new long[categoryNames.length];
			int i = 0;

			for (String categoryNameToken : categoryNames) {
				String[] categoryNameTokenArray = categoryNameToken.split("\\|");

				String vocabularyName = null;
				String categoryName = null;
				if (categoryNameTokenArray.length >= 2) {
					vocabularyName = categoryNameTokenArray[0];
					categoryName = categoryNameTokenArray[1];
				} else if (categoryNameTokenArray.length >= 1) {
					categoryName = categoryNameTokenArray[0];
				}

				AssetCategory category = null;
				long vocabId = 0;
				if (vocabularyName != null) {
					try {
						AssetVocabulary vocab = AssetVocabularyLocalServiceUtil.getGroupVocabulary(groupId,
								vocabularyName);
						vocabId = vocab.getVocabularyId();
					} catch (NoSuchVocabularyException nsv) {
						// do nothing
					}
				}

				if (vocabId != 0) {
					category = ImportLocalServiceUtil.getCategory(groupId, companyId, categoryName, vocabId);
				} else {
					category = ImportLocalServiceUtil.getCategory(groupId, companyId, categoryName);
				}

				categoryIds[i++] = category.getPrimaryKey();
			}
		}

		return categoryIds;
	}

	protected Map<String, String> getCustomFieldValues(Properties properties) {
		Map<String, String> map = new HashMap<String, String>();

		String customFields = properties.getProperty("Custom Fields");

		if (StringUtils.isNotBlank(customFields)) {
			String[] customFieldsArray = customFields.split("\\|");
			if ((customFieldsArray != null) && (customFieldsArray.length > 0)) {
				for (String fieldStr : customFieldsArray) {
					String[] fieldValues = fieldStr.split("\\=");
					if ((fieldValues != null) && (fieldValues.length > 0)) {
						map.put(fieldValues[0], fieldValues[1]);
					}
				}
			}
		}

		return map;
	}

	protected Organization createOrganization(Properties properties) throws Exception {

		String name = properties.getProperty("Name");
		String description = properties.getProperty("Description");
		String type = properties.getProperty("Type");
		String friendlyUrl = properties.getProperty("FriendlyUrl");
		String parent = properties.getProperty("Parent");
		Boolean staging = Boolean.parseBoolean(properties.getProperty("Staging"));
		String typeSettings = properties.getProperty("TypeSettings");
		String comment = properties.getProperty("Comment");

		Map<String, String> customFields = getCustomFieldValues(properties);

		boolean alwaysUpdateMetadata = getAlwaysUpdateMetadata(properties);

		String rowId = properties.getProperty(EXCEL_ROW);

		Organization organization = ImportLocalServiceUtil.createOrganization(user, log, name, description, type,
				parent, friendlyUrl, staging, typeSettings, rowId, comment, companyId, customFields,
				alwaysUpdateMetadata);

		return organization;
	}

	protected void createOrgUserRole(Properties properties) throws Exception {
		String orgName = properties.getProperty("Organization");
		String userName = properties.getProperty("User");
		String roleName = properties.getProperty("Role");

		ImportLocalServiceUtil.createOrgUserRole(companyId, log, orgName, userName, roleName);
	}

	protected ExpandoColumn createCustomFields(Properties properties) throws Exception {

		String className = properties.getProperty("Class Name");
		String tableName = properties.getProperty("Table Name");
		String columnName = properties.getProperty("Column Name");

		String typeString = properties.getProperty("Type");

		int type = 0;
		boolean isInteger = Pattern.matches("^\\d+$", typeString);

		if (isInteger) {
			type = GetterUtil.getInteger(typeString);
		} else {
			// test for one of the values
			int i = 1;
			String labelString = null;

			do {
				labelString = getExpandoTypeName(i);

				if (typeString.equalsIgnoreCase(labelString)) {
					type = i;
					break;
				}

				i++;
			} while (!labelString.equals(ExpandoColumnConstants.UNKNOWN_LABEL));

			if (type == 0) {
				// not found
				System.err.println("Custom Field type '" + typeString + "' not valid, ignoring");
				return null;
			}
		}

		Object defaultData = convertDefaultData(type, properties.getProperty("Default Data"));
		String typeSettings = properties.getProperty("Type Settings");

		return ImportLocalServiceUtil.createCustomField(companyId, log, className, tableName, columnName, type,
				defaultData, typeSettings);
	}

	protected String getExpandoTypeName(int type) {
		if (type == ExpandoColumnConstants.BOOLEAN) {
			return "boolean";
		} else if (type == ExpandoColumnConstants.BOOLEAN_ARRAY) {
			return "boolean[]";
		} else if (type == ExpandoColumnConstants.DATE) {
			return "Date";
		} else if (type == ExpandoColumnConstants.DATE_ARRAY) {
			return "Date[]";
		} else if (type == ExpandoColumnConstants.DOUBLE) {
			return "double";
		} else if (type == ExpandoColumnConstants.DOUBLE_ARRAY) {
			return "double[]";
		} else if (type == ExpandoColumnConstants.FLOAT) {
			return "float";
		} else if (type == ExpandoColumnConstants.FLOAT_ARRAY) {
			return "float[]";
		} else if (type == ExpandoColumnConstants.INTEGER) {
			return "int";
		} else if (type == ExpandoColumnConstants.INTEGER_ARRAY) {
			return "int[]";
		} else if (type == ExpandoColumnConstants.LONG) {
			return "long";
		} else if (type == ExpandoColumnConstants.LONG_ARRAY) {
			return "long[]";
		} else if (type == ExpandoColumnConstants.SHORT) {
			return "short";
		} else if (type == ExpandoColumnConstants.SHORT_ARRAY) {
			return "short[]";
		} else if (type == ExpandoColumnConstants.STRING) {
			return "String";
		} else if (type == ExpandoColumnConstants.STRING_ARRAY) {
			return "String[]";
		}

		return ExpandoColumnConstants.UNKNOWN_LABEL;
	}

	// convert default data to the correct type
	protected Object convertDefaultData(int type, String defaultData) {
		if (defaultData == null) {
			return null;
		}

		// check if this is Array type
		String[] itemList = null;

		if (getExpandoTypeName(type).endsWith("[]")) {
			itemList = StringUtil.split(defaultData);
		}

		if (type == ExpandoColumnConstants.BOOLEAN) {
			return Boolean.parseBoolean(defaultData);
		} else if (type == ExpandoColumnConstants.BOOLEAN_ARRAY) {
			boolean[] array = new boolean[itemList.length];

			for (int i = 0; i < itemList.length; i++) {
				array[i] = Boolean.parseBoolean(itemList[i]);
			}

			return array;
		} else if (type == ExpandoColumnConstants.DATE) {
			try {
				return dateFormat.parse(defaultData);
			} catch (ParseException pe) {
				System.err.println(pe.toString());
				return null;
			}
		} else if (type == ExpandoColumnConstants.DATE_ARRAY) {
			Date[] array = new Date[itemList.length];

			for (int i = 0; i < itemList.length; i++) {
				try {
					array[i] = dateFormat.parse(itemList[i]);
				} catch (ParseException pe) {
					System.err.println(pe.toString());
				}
			}

			return array;
		} else if (type == ExpandoColumnConstants.DOUBLE) {
			return Double.parseDouble(defaultData);
		} else if (type == ExpandoColumnConstants.DOUBLE_ARRAY) {
			double[] array = new double[itemList.length];

			for (int i = 0; i < itemList.length; i++) {
				array[i] = Double.parseDouble(itemList[i]);
			}

			return array;
		} else if (type == ExpandoColumnConstants.FLOAT) {
			return Float.parseFloat(defaultData);
		} else if (type == ExpandoColumnConstants.FLOAT_ARRAY) {
			float[] array = new float[itemList.length];

			for (int i = 0; i < itemList.length; i++) {
				array[i] = Float.parseFloat(itemList[i]);
			}

			return array;
		} else if (type == ExpandoColumnConstants.INTEGER) {
			return Integer.parseInt(defaultData);
		} else if (type == ExpandoColumnConstants.INTEGER_ARRAY) {
			int[] array = new int[itemList.length];

			for (int i = 0; i < itemList.length; i++) {
				array[i] = Integer.parseInt(itemList[i]);
			}

			return array;
		} else if (type == ExpandoColumnConstants.LONG) {
			return Long.parseLong(defaultData);
		} else if (type == ExpandoColumnConstants.LONG_ARRAY) {
			long[] array = new long[itemList.length];

			for (int i = 0; i < itemList.length; i++) {
				array[i] = Long.parseLong(itemList[i]);
			}

			return array;
		} else if (type == ExpandoColumnConstants.SHORT) {
			return Short.parseShort(defaultData);
		} else if (type == ExpandoColumnConstants.SHORT_ARRAY) {
			short[] array = new short[itemList.length];

			for (int i = 0; i < itemList.length; i++) {
				array[i] = Short.parseShort(itemList[i]);
			}

			return array;
		} else if (type == ExpandoColumnConstants.STRING) {
			return defaultData;
		} else if (type == ExpandoColumnConstants.STRING_ARRAY) {
			return itemList;
		}

		return null;
	}

	protected void createResourcePermissions(Properties properties) throws Exception {
		String scopeGroupName = getGroupProperty(properties);
		String scopeName = properties.getProperty("Scope");
		String resource = properties.getProperty("Resource");
		String primaryKey = properties.getProperty("Primary Key");
		String roleName = properties.getProperty("Role");
		String actions = properties.getProperty("Actions");

		ImportLocalServiceUtil.createResourcePermissions(companyId, log, scopeGroupName, scopeName, resource,
				primaryKey, roleName, actions);
	}

	protected AssetCategory createCategory(Properties properties) throws Exception {
		String groupName = getGroupProperty(properties);
		String name = properties.getProperty("Name");
		String description = properties.getProperty("Description");
		String vocabulary = properties.getProperty("Vocabulary");
		String parentCategory = properties.getProperty("Parent Category");
		String globalCategory = properties.getProperty("Global Category");
		String staticCategoryId = properties.getProperty("Static Category ID");

		Group group = ImportLocalServiceUtil.getGroup(user.getCompanyId(), groupName);

		AssetCategory category = ImportLocalServiceUtil.createCategory(user, log, group, name, description, vocabulary,
				parentCategory, globalCategory, staticCategoryId);

		return category;
	}

	protected DDMStructure createDataDefinition(Properties properties) throws Exception {
		boolean updateIfExists = getUpdateIfExists(properties);

		String groupName = getGroupProperty(properties);
		String name = properties.getProperty("Name");
		String description = properties.getProperty("Description");
		String schema = properties.getProperty("Schema");

		Group group = ImportLocalServiceUtil.getGroup(user.getCompanyId(), groupName);

		String className = "com.liferay.portlet.dynamicdatalists.model.DDLRecordSet";
		String type = "Data Definition";

		DDMStructure structure = ImportLocalServiceUtil.createDDMStructure(user, log, type, group, className, name,
				description, schema, updateIfExists);

		return structure;
	}

	protected DDLRecordSet createDynamicDataList(Properties properties) throws Exception {
		boolean updateIfExists = getUpdateIfExists(properties);

		String groupName = getGroupProperty(properties);
		String name = properties.getProperty("Name");
		String description = properties.getProperty("Description");
		String dataDefinition = properties.getProperty("Data Definition");

		Group group = ImportLocalServiceUtil.getGroup(user.getCompanyId(), groupName);

		DDLRecordSet recordSet = ImportLocalServiceUtil.createDDLRecordSet(user, log, group, name, description,
				dataDefinition, updateIfExists);

		return recordSet;
	}

	protected List<DDLRecord> createDynamicDataListRecord(Properties properties) throws Exception {
		boolean updateIfExists = getUpdateIfExists(properties);
		
		String replaceStr = properties.getProperty("Replace Completely");
		boolean replace = replaceStr != null && Boolean.parseBoolean(replaceStr);
		
		String configurationStr = properties.getProperty("Is Configuration");
		boolean configuration = configurationStr != null && Boolean.parseBoolean(configurationStr);
		
		String groupName = getGroupProperty(properties);
		String dataList = properties.getProperty("Data List");
		String csv = properties.getProperty("Content CSV");

		Group group = ImportLocalServiceUtil.getGroup(user.getCompanyId(), groupName);

		List<DDLRecord> records = ImportLocalServiceUtil.createDDLRecords(user, log, group, dataList, csv, updateIfExists, replace, configuration);

		return records;
	}

	protected LayoutPrototype createPageTemplate(Properties properties) throws Exception {
		String name = properties.getProperty("Name");
		String description = properties.getProperty("Description");
		String theme = properties.getProperty("Theme");
		String colorScheme = properties.getProperty("Color Scheme");

		if (theme == null) {
			theme = "";
		}

		String typeSettings = properties.getProperty("TypeSettings");
		String layoutTemplate = properties.getProperty("Layout Template");

		List<String[]> columnPortlets = new ArrayList<String[]>();

		for (int i = 0; i < NUM_COLUMNS; i++) {
			String columnPortlet = properties.getProperty("Column" + i + " Portlets");
			if (StringUtils.isNotBlank(columnPortlet)) {
				String[] columnArray = new String[2];
				columnArray[0] = Integer.toString(i);
				columnArray[1] = columnPortlet;
				columnPortlets.add(columnArray);
			}
		}

		// String column1Portlets=properties.getProperty("Column1 Portlets");
		// String column2Portlets=properties.getProperty("Column2 Portlets");
		// String column3Portlets=properties.getProperty("Column3 Portlets");
		// String column4Portlets=properties.getProperty("Column4 Portlets");
		// String column5Portlets=properties.getProperty("Column5 Portlets");
		// String column6Portlets=properties.getProperty("Column6 Portlets");
		// String column7Portlets=properties.getProperty("Column7 Portlets");
		// String column8Portlets=properties.getProperty("Column8 Portlets");
		// String column9Portlets=properties.getProperty("Column9 Portlets");

		boolean updateIfExists = getUpdateIfExists(properties);

		// LayoutPrototype layoutPrototype =
		// ImportLocalServiceUtil.createLayoutPrototype(user, log, name,
		// description, theme, colorScheme, layoutTemplate, typeSettings,
		// column1Portlets, column2Portlets, column3Portlets, column4Portlets,
		// column5Portlets,
		// column6Portlets, column7Portlets, column8Portlets, column9Portlets,
		// updateIfExists);
		LayoutPrototype layoutPrototype = ImportLocalServiceUtil.createLayoutPrototype(user, log, name, description,
				theme, colorScheme, layoutTemplate, typeSettings, columnPortlets, updateIfExists);

		return layoutPrototype;
	}

	protected Layout createPageTemplateLayout(Properties properties) throws Exception {
		String groupName = getGroupProperty(properties);
		String template = properties.getProperty("Page Template");
		String name = properties.getProperty("Name");
		String description = properties.getProperty("Description");
		String friendlyUrl = properties.getProperty("Friendly URL");
		Boolean private_ = Boolean.parseBoolean(properties.getProperty("Private"));
		Boolean hidden = Boolean.parseBoolean(properties.getProperty("Hidden"));
		String parentFriendlyUrl = properties.getProperty("Parent Friendly URL");

		Group group = ImportLocalServiceUtil.getGroup(user.getCompanyId(), groupName);

		Layout layout = ImportLocalServiceUtil.createPageTemplateLayout(user, log, template, group, name, description,
				friendlyUrl, private_, hidden, parentFriendlyUrl);

		return layout;
	}

	protected LayoutSetPrototype createSiteTemplate(Properties properties) throws Exception {
		String name = properties.getProperty("Name");
		String description = properties.getProperty("Description");
		Boolean layoutsUpdatable = Boolean.parseBoolean(properties.getProperty("Layouts Updatable"));

		boolean updateIfExists = getUpdateIfExists(properties);

		LayoutSetPrototype siteTemplate = ImportLocalServiceUtil.createLayoutSetPrototype(user, log, name, description,
				layoutsUpdatable, updateIfExists);

		return siteTemplate;
	}

	protected Layout createSiteTemplateLayout(Properties properties) throws Exception {
		String siteTemplateName = properties.getProperty("Site Template");
		String pageTemplate = properties.getProperty("Page Template");

		LayoutSetPrototype siteTemplate = ImportLocalServiceUtil.getLayoutSetPrototype(companyId, siteTemplateName);

		Group group = siteTemplate.getGroup();

		if (pageTemplate == null || pageTemplate.isEmpty()) {
			properties.setProperty("Group", group.getName());
			properties.setProperty("Private", String.valueOf(true));
			properties.setProperty("Hidden", String.valueOf(false));

			Layout layout = createLayout(properties);

			return layout;
		} else {
			// create a page template
			properties.setProperty("Group", group.getName());
			properties.setProperty("Private", String.valueOf(true));

			Layout layout = createPageTemplateLayout(properties);

			return layout;
		}
	}
}
ExcelUtil——2013-03-14 10:59:45
package com.endplay.util.excel;

import java.io.InputStream;
import java.util.*;
import java.net.URL;
import java.net.URLConnection;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;

/**
 */
public class ExcelUtil
{
   /**
    * Create a Workbook object from a file in the file system.
    */
   public static Workbook getWorkbook (String templateXls) throws ExcelException {
      try {
	    java.io.InputStream inputStream = new java.io.FileInputStream(templateXls);

		if (inputStream==null) {
		   // file not found; attempt to retrieve via from class loader
      	   inputStream = ExcelUtil.class.getResourceAsStream(templateXls);
        }

		Workbook workBook = WorkbookFactory.create(inputStream);
		inputStream.close();

		return workBook;
	  }
	  catch (Exception ex) {
	     throw new ExcelException(ex);
	  }
   }


   /**
    * Create a Workbook object from a file through the class loader (e.g. from jar).
    */
   public static Workbook getWorkbookResource (String templateXls) throws ExcelException {
      try {
		InputStream inputStream = ExcelUtil.class.getResourceAsStream(templateXls);
		Workbook workBook = WorkbookFactory.create(inputStream);
		inputStream.close();

		return workBook;
	  }
	  catch (Exception ex) {
	     throw new ExcelException(ex);
	  }
   }


   /**
    * Create a Workbook object from an URL
    */
   public static Workbook getWorkbook(URL url) throws ExcelException {
      try {
		URLConnection urlCon = url.openConnection();
		InputStream inputStream = urlCon.getInputStream();
		Workbook workBook = WorkbookFactory.create(inputStream);
		inputStream.close();

		return workBook;
	  }
	  catch (Exception ex) {
	     throw new ExcelException(ex);
	  }
   }


   /**
    * Create a Workbook object from an InputStream
    */
   public static Workbook getWorkbook(InputStream inputStream) throws ExcelException {
      try {
  		Workbook workBook = WorkbookFactory.create(inputStream);

		return workBook;
	  }
	  catch (Exception ex) {
	     throw new ExcelException(ex);
	  }
      finally {
		try {
			inputStream.close();
		}
		catch (Exception e) {
			// ignore
		}
      }
   }


   /**
    * Get Cell object at the x,y coordinate.
    */
   public static Cell getCell (Sheet sheet, int colNum, int rowNum) {
      // rows are zero based
      Row row = sheet.getRow(rowNum);

	  // create row if it doesn't exist
	  if (row == null) {
	    return null;
	  }

      Cell cell = row.getCell(colNum);
	  return cell;
   }


   /**
    * Return cell at the location.  If the cell doesn't exist, then create it
    */
   public static Cell getCellOrCreate (Sheet sheet, int colNum, int rowNum) {
	  // get the row
	  Row row = sheet.getRow(rowNum);

	  if (row==null) {
	     // create a new row
		 row = sheet.createRow(rowNum);
	  }

      Cell cell = row.getCell(colNum);

	  // create a new cell
	  return (cell==null) ? row.createCell(colNum) : cell;
   }



   /**
    * Get  column from Excel column (e.g. "AZ")
    */
   public static int getSSColumn (String column) {
      int colNum = -1;

      switch (column.length()) {

         case 1 :
            colNum = column.charAt(0) - 'A';
            break;

         case 2 :
           colNum = (column.charAt(0) - 'A' + 1) * 26 + (column.charAt(1) - 'A');
            break;

         case 0 :
            System.err.println("column reference missing: " + column);
            break;

         default :
            System.err.println("column reference too large: " + column);
            break;
      }

	  return colNum;
   }


   /**
    * Get  row from Excel row
    */
   public static int getSSRow (int rowNum) {
	  return rowNum-1;
   }


   /**
    * Get Excel column (e.g. "AZ") from  column
    */
   public static String getExcelColumn (int colNum) {
      String column = "";

      char msb = (char) (colNum/26);

	  if (msb != 0) {
	    msb--;
	    msb += 'A';
	    column += msb;
	  }

	  char lsb = (char) (colNum%26);
	  lsb += 'A';
      column += lsb;

	  return column;
   }


   /**
    * Get Excel row from  column
    */
   public static int getExcelRow (int row) {
	  return row+1;
   }


   /**
    * Set a cell to the given value
    */
   public static void setCellValue(Sheet sheet, int colNum, int rowNum, String value) throws ExcelException {
     try {
        Cell cell = getCellOrCreate(sheet, colNum, rowNum);

		 cell.setCellValue(value);
      }
	  catch (Exception ex) {
	    throw new ExcelException(ex);
	  }
   }


   /**
    * Set a cell to the given value
    */
   public static void setCellValue(Sheet sheet, int colNum, int rowNum, double value) throws ExcelException {
     try {
        Cell cell = getCellOrCreate(sheet, colNum, rowNum);

		 cell.setCellValue(value);
      }
	  catch (Exception ex) {
	    throw new ExcelException(ex);
	  }
   }


   /**
    * Set a cell to the given value
    */
   public static void setCellValue(Sheet sheet, int colNum, int rowNum, Date value) throws ExcelException {
     try {
        Cell cell = getCellOrCreate(sheet, colNum, rowNum);

		if (value != null) {
		   cell.setCellValue(value);
		}
		else {
		   cell.setCellType(Cell.CELL_TYPE_BLANK);
		}
      }
	  catch (Exception ex) {
	    throw new ExcelException(ex);
	  }
   }


   /**
    * Set a cell to the given value
    */
   public static void setCellValue(Sheet sheet, int colNum, int rowNum, boolean value) throws ExcelException {
     try {
        Cell cell = getCellOrCreate(sheet, colNum, rowNum);

                 cell.setCellValue(value);
      }
          catch (Exception ex) {
            throw new ExcelException(ex);
          }
   }


   /**
    * Set a cell to the given value
    */
   public static void setCellBlank(Sheet sheet, int colNum, int rowNum) throws ExcelException {
     try {
        Cell cell = getCell(sheet, colNum, rowNum);

        if (cell != null) {
          cell.setCellType(Cell.CELL_TYPE_BLANK);
        }
      }
      catch (Exception ex) {
         throw new ExcelException(ex);
      }
   }

   /**
    * Delete rows
    */
   public static void deleteRows(Sheet sheet, int topRow, int bottomRow) {
        // remove template rows.
		for (int i=topRow; i<=bottomRow; i++) {
		   Row row = sheet.getRow(i);

		   if (row != null) {
 		      sheet.removeRow(row);
		   }
		}
   }


   /**
    * Copy cell formatting & value to another cell
    */
   public static void copyCell(Cell source, Cell dest) throws ExcelException {
     try {
	     int type = source.getCellType();

         // copy cell type
		 dest.setCellType(type);

         // copy cell value
		 switch (type) {
		     case Cell.CELL_TYPE_BLANK:
			    break;

		     case Cell.CELL_TYPE_NUMERIC:
			    dest.setCellValue(source.getNumericCellValue());
				break;

		     case Cell.CELL_TYPE_FORMULA:
			    // need to translate the cell formula!
				String formula = source.getCellFormula();
			    dest.setCellFormula(formula);
				break;

		     case Cell.CELL_TYPE_STRING:
			    dest.setCellValue(source.getStringCellValue());
			    break;

			 default:
			   throw new ExcelException("Copying of cell with type: "+type+" not supported");
		 }

		 // copy style
		 dest.setCellStyle(source.getCellStyle());
      }
	  catch (Exception ex) {
	    throw new ExcelException(ex);
	  }
   }


   /**
    * Delete merged regions
    */
   public static void deleteMergedRegions(Sheet sheet) throws ExcelException {
      int numRegions = sheet.getNumMergedRegions();

	  // remove regions in descending order
	  for (int i=numRegions-1; i>=0; i--) {
		 sheet.removeMergedRegion(i);
	  }
   }


   /**
    * Set cell style
    */
  public static void setCellStyle(Sheet sheet, int column, int rowNum, CellStyle style) {
     Cell cell = getCellOrCreate(sheet, column, rowNum);
     cell.setCellStyle(style);
  }


   /**
    * Set cell formula
    */
  public static void setCellFormula(Sheet sheet, int column, int rowNum, String formula) {
     Cell cell = getCellOrCreate(sheet, column, rowNum);

     cell.setCellFormula(formula);
  }

   /**
    * Get Cell range reference
    */
    public static String getCellRangeReference(int leftCol, int topRow, int rightCol, int bottomRow) {
	   return getExcelColumn(leftCol)+getExcelRow(topRow)+":"+getExcelColumn(rightCol)+getExcelRow(bottomRow);
    }

    /**
     * Get Cell reference
     */
 	public static String getCellReference(Sheet sheet, int col, int row) {
 	  return sheet.getSheetName()+"!"+ExcelUtil.getCellReference(col, row);
 	}

   /**
    * Get Cell reference
    */
	public static String getCellReference(int col, int row) {
	  return ExcelUtil.getExcelColumn(col)+ExcelUtil.getExcelRow(row);
	}

   /**
    * Merge cells together
    */
  public static void mergeCells(Sheet sheet, int left, int top, int right, int bottom) {
     sheet.addMergedRegion(new CellRangeAddress(top, left, bottom, right));
  }

   /**
    * Format cells
    */
  public static void formatCellRange(Sheet sheet, int left, int top, int right, int bottom, CellStyle style) {
     for (int i=left; i<=right; i++) {
	   for (int j=top; j<=bottom; j++) {
	      Cell cell=ExcelUtil.getCell(sheet, i, j);
		  cell.setCellStyle(style);
	   }
	 }
  }

   /**
    * Set sheet name
    */
  public static void setSheetName(Workbook workBook, int sheetIndex, String sheetName) {
      // POI 1.7 bug-if sheet name is duplicated, Excel will crash upon close
      Sheet existingSheet = workBook.getSheet(sheetName);

      if (existingSheet != null) {
        // to ensure uniqueness, pad with spaces
         do {
           sheetName += " ";

           existingSheet = workBook.getSheet(sheetName);
         } while (existingSheet != null);

         workBook.setSheetName(sheetIndex, sheetName);
      }

      workBook.setSheetName(sheetIndex, sheetName);
  }

  /**
   * Get Cell value as Object at the x,y coordinate.
   */
  public static Object getCellValue (Sheet sheet, int colNum, int rowNum) throws ExcelException {
     Cell cell = getCell(sheet, colNum, rowNum);

     if (cell == null) {
        return null;
     }
     else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
        return cell.getRichStringCellValue().getString().trim();
     }
     else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
        return null;
     }
     else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
   	  	return cell.getBooleanCellValue();
      }
     else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
    	 if (DateUtil.isCellDateFormatted(cell)) {
    		 return cell.getDateCellValue();
    	 }
    	 else {
    		 return cell.getNumericCellValue();
    	 }
     }
     else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
         return cell.getCellFormula();
     }
     else {
         throw new ExcelException("Unsupported cell type "+cell.getCellType()+" @ "+sheet.getSheetName()+"!"+ExcelUtil.getCellReference(colNum, rowNum));
     }
  }

   /**
    * Get Cell value as String at the x,y coordinate.
    */
   public static String getCellStringValue (Sheet sheet, int colNum, int rowNum) throws ExcelException {
      Cell cell = getCell(sheet, colNum, rowNum);

      if (cell == null) {
         return null;
      }
      else if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
         return cell.getStringCellValue().trim();
      }
      else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
         return null;
      }
      else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
    	  boolean value = cell.getBooleanCellValue();
          return Boolean.toString(value);
       }
      else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
         String stringValue = Double.toString(cell.getNumericCellValue());

         // trim .0 if present
         return stringValue.endsWith(".0") ? stringValue.substring(0, stringValue.length()-2) : stringValue;
      }
      else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
          return cell.getCellFormula();
      }
      else {
          throw new ExcelException("Get string from cell type "+cell.getCellType()+" not supported @ "+sheet.getSheetName()+"!"+ExcelUtil.getCellReference(colNum, rowNum));
      }
   }

   /**
    * Get Cell value as double at the x,y coordinate.
    */
   public static double getCellDoubleValue (Sheet sheet, int colNum, int rowNum) throws ExcelException {
      Cell cell = getCell(sheet, colNum, rowNum);

      if (cell == null || cell.getCellType() == Cell.CELL_TYPE_BLANK) {
         return 0.0;
      }
      else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
         return cell.getNumericCellValue();
      }
      else {
          throw new ExcelException("Get number from cell type "+cell.getCellType()+" not supported @ "+sheet.getSheetName()+"!"+ExcelUtil.getCellReference(colNum, rowNum));
      }
   }

   /**
    * Get Cell value as a Date at the x,y coordinate.
    */
   public static Date getCellDateValue (Sheet sheet, int colNum, int rowNum) {
      Cell cell = getCell(sheet, colNum, rowNum);

      if (cell == null) {
         return null;
      }
      else {
         return cell.getDateCellValue();
      }
   }

   /**
    * Get Cell value as a boolean at the x,y coordinate.
    */
   public static boolean getCellBooleanValue (Sheet sheet, int colNum, int rowNum) {
      Cell cell = getCell(sheet, colNum, rowNum);

      if (cell == null) {
         return false;
      }
      else {
         return cell.getBooleanCellValue();
      }
   }

   /**
    * Get CellStyle at the x,y coordinate.
    */
   public static CellStyle getCellStyle (Sheet sheet, int colNum, int rowNum) {
      Cell cell = getCell(sheet, colNum, rowNum);

      if (cell == null) {
         return null;
      }
      else {
         return cell.getCellStyle();
      }
   }

   /**
    * Get CellStyles.  For legends.
    */
   public static List<CellStyle> getCellStyles(Sheet sheet, int colNum, int topRow, int bottomRow) {
     int size = bottomRow-topRow+1;
     List<CellStyle> styles = new ArrayList<CellStyle>(size);

     for (int i=topRow; i<=bottomRow; i++) {
       styles.add(getCellStyle(sheet, colNum, i));
     }

     return styles;
   }


   /**
    * Clone cell style
    */
    public static CellStyle cloneCellStyle(Workbook workBook, CellStyle source) {
      CellStyle cellStyle = workBook.createCellStyle();
      cellStyle.setAlignment(source.getAlignment());
      cellStyle.setBorderBottom(source.getBorderBottom());
      cellStyle.setBorderLeft(source.getBorderLeft());
      cellStyle.setBorderRight(source.getBorderRight());
      cellStyle.setBorderTop(source.getBorderTop());
      cellStyle.setBottomBorderColor(source.getBottomBorderColor());
      cellStyle.setDataFormat(source.getDataFormat());
      cellStyle.setFillBackgroundColor(source.getFillBackgroundColor());
      cellStyle.setFillForegroundColor(source.getFillForegroundColor());
      cellStyle.setFillPattern(source.getFillPattern());
      cellStyle.setFont(workBook.getFontAt(source.getFontIndex()));
      cellStyle.setHidden(source.getHidden());
      cellStyle.setIndention(source.getIndention());
      cellStyle.setLeftBorderColor(source.getLeftBorderColor());
      cellStyle.setLocked(source.getLocked());
      cellStyle.setRightBorderColor(source.getRightBorderColor());
      cellStyle.setRotation(source.getRotation());
      cellStyle.setTopBorderColor(source.getTopBorderColor());
      cellStyle.setVerticalAlignment(source.getVerticalAlignment());
      cellStyle.setWrapText(source.getWrapText());

      return cellStyle;
    }


    /**
     * Set Cell as the active cell
     */
    public static void setActiveCell (Sheet sheet, int colNum, int rowNum) {
       Cell cell = getCell(sheet, colNum, rowNum);

       cell.setAsActiveCell();
    }
}
action_2013-03-14 10:59:01
package com.endplay.dataimport.portlet;

import com.endplay.dataimport.portlet.model.ImportLog;
import com.endplay.dataimport.portlet.service.ImportLogLocalServiceUtil;
import com.endplay.dataimport.util.ExcelImport;
import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.servlet.SessionErrors;
import com.liferay.portal.kernel.upload.UploadException;
import com.liferay.portal.kernel.upload.UploadPortletRequest;
import com.liferay.portal.kernel.zip.ZipReader;
import com.liferay.portal.kernel.zip.ZipReaderFactoryUtil;
import com.liferay.portal.model.User;
import com.liferay.portal.util.PortalUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

public class DataImportPortlet extends MVCPortlet {
	private static Log log = LogFactoryUtil.getLog(DataImportPortlet.class);
	
	public void doView(
			RenderRequest renderRequest, RenderResponse renderResponse)
		throws IOException, PortletException {
		
		// clear errors
		SessionErrors.clear(renderRequest);

		try {
			List<ImportLog> recent = ImportLogLocalServiceUtil.getImportLogs(-1, -1);
			
			renderRequest.setAttribute("recent", recent);
		}
		catch (Exception ex) {
			log.error(ex);
		}
		
		super.doView(renderRequest, renderResponse);
	}

	public void uploadFile(ActionRequest actionRequest, ActionResponse actionResponse) throws Exception {
		UploadPortletRequest uploadPortletRequest =
			PortalUtil.getUploadPortletRequest(actionRequest);

		String fileName = uploadPortletRequest.getFileName("fileName");
		InputStream inputStream = uploadPortletRequest.getFileAsStream("fileName");
		List<String> errors = new ArrayList<String>();
		if (inputStream == null) {
			throw new UploadException();
		}
		
		User user = PortalUtil.getUser(uploadPortletRequest);
		
//		if (fileName.endsWith("txt")) {
//			InputStreamReader isr = null;
//			BufferedReader ir = null;
//			try {
//				isr = new InputStreamReader(inputStream);
//				ir = new BufferedReader(isr);
//				String line = null;
//				File file = null;
//				FileInputStream fileInputStream = null;
//				while ((line = ir.readLine()) != null) {
//					try {
//						file = new File(line);
//						fileInputStream = new FileInputStream(file); 
//						
//						line = line.substring(line.lastIndexOf("/"));
//						doFileUpload(actionRequest, user, line, fileInputStream);
//						
//						log.info("successfully imported " + line);
//					}
//					catch (Exception e) {
//						log.warn("failed to import " + line);
//					}
//					finally {
//						if (fileInputStream != null) {
//							fileInputStream.close();
//						}
//					}
//				}
//			}
//			finally {
//				if (ir != null) {
//					ir.close();
//				}
//			}
//		}
		try
		{
			if (fileName.endsWith(".zip")) 
			{
				log.info("Data Import Archive Start : " + fileName);
				ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(inputStream);
				List<String> entries = zipReader.getEntries();
				boolean manifestFound = false;
				for (String entry : entries)
				{
					if (entry.endsWith(".txt"))
					{
						manifestFound = true;
						InputStreamReader isr = null;
						BufferedReader ir = null;
						InputStream textFileInputStream = null;
						try {
								textFileInputStream = zipReader.getEntryAsInputStream(entry);
								isr = new InputStreamReader(textFileInputStream);
								ir = new BufferedReader(isr);
								String line = null;
								File file = null;
								InputStream importInputStream = null;
								while ((line = ir.readLine()) != null) {
									try {
										file = new File(line);
										importInputStream = zipReader.getEntryAsInputStream(file.getName());
										doFileUpload(actionRequest, user, file.getName(), importInputStream,errors);
										log.info("Import processed: " + line);
									}
									catch (Exception e) {
										log.error("Import failed " + file.getName() + " !!!. Stopping import of files from archive: " + fileName);
										break;
									}
									finally {
										if (importInputStream != null) {
											importInputStream.close();
										}
									}
								}
						}
						finally {
							if (ir != null) {
								ir.close();
							}
							if (textFileInputStream != null)
							{
								textFileInputStream.close();
							}
						}
					}
				}
				
				if (!manifestFound)
				{
						String errMsg = "No manifest file found in archive " + fileName + " !!!";
						actionRequest.setAttribute("error", errMsg);
						errors.add(errMsg);
						log.error(errMsg);
				}
				log.info("Data Import Archive End : " + fileName);
			}		
			else {
				doFileUpload(actionRequest, user, fileName, inputStream,errors);
			}
		}
		finally
		{
			if (CollectionUtils.isNotEmpty(errors))
			{
				for (String errorMsg : errors)
				{
					SessionErrors.add(actionRequest, errorMsg);
				}
			}
		}
	}
	
	protected void doFileUpload(ActionRequest actionRequest, User user, 
		String fileName, InputStream inputStream, List<String> errors) throws Exception {
		List<ImportLog> importLogs = ImportLogLocalServiceUtil.searchImportLogs(fileName);
		if (CollectionUtils.isNotEmpty(importLogs) && importLogs.size() >= 1)
		{
			log.info("Skipping data import for file:"+ fileName);
			return;
		}
		
		ImportLog entry = ImportLogLocalServiceUtil.createImportLog(0);
		entry.setUserId(user.getUserId());
		entry.setImportDate(new Date());
		entry.setFileName(fileName);
		entry.setStatus("started");
		entry = ImportLogLocalServiceUtil.addImportLog(entry);
		entry.setCompanyId(user.getCompanyId());
		
		ExcelImport importer = null;
		try {
			importer = new ExcelImport(user);
			importer.processExcel(inputStream);
			
			entry.setStatus("success");
			entry = ImportLogLocalServiceUtil.updateImportLog(entry);
		}
		catch (Exception ex) {
			actionRequest.setAttribute("error", ex);
			
			String errMsg = ex.getMessage();
			
			if (errMsg == null) {
				errMsg = ex.toString();
			}
			
			//SessionErrors.add(actionRequest, errMsg);
			errors.add(errMsg);
			log.error(ex);
			
			entry.setStatus("error");
			entry.setDetail(errMsg);
			entry = ImportLogLocalServiceUtil.updateImportLog(entry);
			throw new Exception(ex);
		}
		finally {
			actionRequest.getPortletSession().setAttribute("log", importer.getLogEntries());
		}
	}
}
view.jsp——2013-03-14 10:57:06
<%
WindowState windowState = renderRequest.getWindowState();

String currentURL = PortalUtil.getCurrentURL(request);
%>

<%@ include file="/jsp/init.jsp" %>
<%@ page import="com.endplay.dataimport.portlet.model.ImportLog" %>

<portlet:defineObjects />

<%
List<String> log = (List<String>)renderRequest.getPortletSession().getAttribute("log");
if (log != null) {
	renderRequest.getPortletSession().removeAttribute("log");
}

List<ImportLog> recent = (List<ImportLog>)renderRequest.getAttribute("recent");

Exception error = (Exception)request.getAttribute("error");
%>
		<c:if test="<%= error != null %>">
			<span class="portlet-msg-error"><%= error.getMessage() %></span>
		</c:if>
		
		<c:if test="<%= log != null %>">
			<a href="#results">View Import Results</a>
		</c:if>
		
		<portlet:actionURL var="dataImportURL" name="uploadFile" >
			<portlet:param name="redirect" value="<%= currentURL %>" />
		</portlet:actionURL>

		<aui:form action="<%= dataImportURL %>" enctype="multipart/form-data" method="post" name="fm">
			<liferay-ui:error exception="<%= Exception.class %>" message="an-unexpected-error-occurred-while-uploading-the-file" />

			<aui:fieldset>
				<aui:input label='<%= LanguageUtil.get(pageContext, "excel-file-or-txt-file") %>' name="fileName" size="50" type="file" />

				<aui:button-row>
					<aui:button value="import-data" type="submit" />
				</aui:button-row>
			</aui:fieldset>
		</aui:form>
		
		<c:if test="<%= error == null && recent != null && !recent.isEmpty() %>">
			<hr/>
			<h1>Most recent imports</h1>
			<c:forEach var="entry" items="<%= recent %>" begin="0" end="99" step="1">
				${entry.importDate} - ${entry.userName} - ${entry.fileName} - ${entry.status} - ${entry.detail}<br/> 
			</c:forEach>
		</c:if>
		
		<c:if test="<%= log != null %>">
			<hr/>
			<a name="results"></a>
			<h1>Import results</h1>
			<c:forEach var="entry" items="<%= log %>">
				${entry}<br/>
			</c:forEach>
		</c:if>
URL
www.theindychannel.com
JSO
<%--
/**
* Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
--%>
<%@ include file="/jsp/init.jsp" %>

<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>

<!--<script src="${pageContext.servletContext.contextPath}/js/quickpublish/javascript.js${STATIC_FILE_SUFFIX}"></script>-->

<script src="${pageContext.servletContext.contextPath}/js/quickpublish/QuickPublish.js${STATIC_FILE_SUFFIX}"></script>

<!--<style type="text/css">

h2.acc_trigger {
	padding: 0;	margin: 0 0 5px 0;
	background: url("${pageContext.servletContext.contextPath}/images/media/accordian_img.gif") no-repeat;	
	height: 46px;	
	line-height: 46px;
	width: 500px;
	font-size: 2em;
	font-weight: normal;
	float: left;
}

</style> -->

<%@page import="com.liferay.portal.kernel.util.WebKeys" %>
<%@page import="com.liferay.portal.model.Layout" %>
<%@page import="com.liferay.portal.theme.ThemeDisplay" %>
<%@page import="com.endplay.portlets.quickpublish.QuickPublishVO"%>
<%@page import="org.codehaus.jackson.JsonFactory"%>
<%@page import="org.codehaus.jackson.map.ObjectMapper"%>
<%@page import="com.endplay.portlets.distribution.DistributionVO"%>

<%
	QuickPublishVO quickPubAttributes = (QuickPublishVO)renderRequest.getAttribute("quickPublishVO");	
	long quickPublishLayoutId = quickPubAttributes.getLayoutId();
	Map<String, String> paramMap = new HashMap<String, String>();
	paramMap.put("type","QuickPublish");	
	renderRequest.setAttribute("params", paramMap);
	DistributionVO distributionVO = quickPubAttributes.getStoryVO().getDistributionVO();
	ObjectMapper mapper = new ObjectMapper(new JsonFactory());
%>

<script type="text/javascript">
var allAuthorsEndPoint = '<%=(String) renderRequest.getPreferences().getValue("AllAuthorsEndPoint", "") %>';
var pageDefaultsEndPoint = '<%=(String) renderRequest.getPreferences().getValue("pageDefaultsEndPoint", "") %>';
var saveEndPoint = '<%=(String) renderRequest.getPreferences().getValue("QuickSaveEndPoint", "") %>?userId='+userId+'&groupId='+groupId;
var publishEndPoint = '<%=(String) renderRequest.getPreferences().getValue("QuickPublishEndPoint", "") %>?userId='+userId+'&groupId='+groupId;
var quickPublishLayoutId = <%=quickPublishLayoutId%>;
var galleryDefaults;
var storyDefaults;
var storyPortletConfig =  {distributionVO : <%= mapper.writeValueAsString(distributionVO)%>};
</script>
<div class="xyz_container">
	<h2 class="acc_trigger active"><a href="#"><span class="icon-arrow-down">▼</span><span class="icon-arrow-right">►</span> <text class="acc_type">Quick Story</text></a></h2>
	<form name="storyForm" id="storyForm">
	<div class="acc_container">	
		<c:import url="story-view.jsp"/>	
	</div>	
	</form>
	<h2 class="acc_trigger acc_media_tab collapsed" style="display:none"><a href="#"><span class="icon-arrow-down">▼</span><span class="icon-arrow-right">►</span> Quick Media</a></h2>
	<div class="acc_container" style="display:none">
		<div class="block">
			<!-- <input type="button" value="Load Image Data" class="btn-text" id="acc_loadData"> -->
			<div class="std-datatable"><c:import url="../media/view.jsp"/></div>
		</div>
	</div>	
	<h2 class="acc_trigger collapsed" style="display:none"><a href="#"><span class="icon-arrow-down">▼</span><span class="icon-arrow-right">►</span> Quick Share/Distribution</a></h2>
	<div class="acc_container" style="display:none">
		<div class="block">
			<c:import url="../story/tab_distribution.jsp" />
		</div>
	</div>	
</div>

<!-- FOOTER publish and other buttons-->
<footer class="acc_footer" style="display:none"> 
	<button class="btn btn-text btn-gradient" id="acc_save">Save Draft</button>
	<button class="btn btn-text btn-gradient" id="acc_reset">Reset</button>
	<button class="btn btn-text btn-gradient btn-gradient_green" id="btn_acc_publish">Publish</button>
	<div class="acc_result block" style="display:none">
	 test
	</div>
</footer>	

<!-- <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js${STATIC_FILE_SUFFIX}"></script> -->
<script type="text/javascript">		

jQuery(document).ready(function($){
//$(".acc_container").hide();
//$(".acc_trigger").hide(); 
//$(".acc_footer").hide();
//$('.acc_trigger:first').show();
//$('.acc_trigger:first').addClass('active').next().show();
//accordian function
//select story by default
$('.Story').attr("selected","selected");
$('.acc_trigger').click(function(){
	//$('.acc_trigger').addClass('collapsed');
	if( $(this).next().is(':hidden') ) { 
		$('.acc_trigger').removeClass('active').next().slideUp(); 
		$(this).toggleClass('active').next().slideDown();
		$('.acc_trigger').addClass('collapsed');
		$(this).removeClass('collapsed');	
	}	
	return false; //Prevent the browser jump to the link anchor
});
//show other tabs and other fields on headline key down.
$('.acc_hide_all').keydown(function(){
	if($(this).hasClass('acc_hide_all')){	
		$(this).removeClass('acc_hide_all');
		//show other attributes		
		$(".acc_story_attributes").slideDown(); 
		//$(".acc_flags").slideDown(); 
		//show other tabs
		$(".acc_trigger").slideDown(); 
		$(".acc_footer").slideDown();
		//quickpublish.js to init the editor.
		initCkeditor('acc_story_abs');
		initCkeditor2('acc_story_body');
		swapTemplatePageType();
		//saveStoryPageDefaults();
		//get authors
		var authorUrl = window.location.protocol + '//'+ window.location.hostname + ':'+ window.location.port + allAuthorsEndPoint;
		getAllAuthors(quickPublishLayoutId, authorUrl);
		
	}
});
//change page type
$('#acc_page_type').change(function(){
	swapTemplatePageType();
	var url = window.location.protocol + '//'+ window.location.hostname + ':'+ window.location.port + pageDefaultsEndPoint;
	var type = $('select[name=acc_page_type]').val();
	swapPageDefault(quickPublishLayoutId, url, type);
});

//change Copyright type
$('#acc_copyright').change(function(){			
	swapCopyright();
});

//get authors on author key down acc_author_auto
/*$('#acc_author').click(function(){
var url = window.location.protocol + '//'+ window.location.hostname + ':'+ window.location.port + allAuthorsEndPoint;
if($(this).hasClass('acc_getoptions')){	
	$(this).removeClass('acc_getoptions');	
	getAllAuthors(quickPublishLayoutId, url);		
}
});*/

//handle save click
$('#acc_save').click(function(){
	var url = window.location.protocol + '//'+ window.location.hostname + ':'+ window.location.port + saveEndPoint;
	read(url);
});
//handle publish click
$('#btn_acc_publish').click(function(){
	var url = window.location.protocol + '//'+ window.location.hostname + ':'+ window.location.port + publishEndPoint;
	read(url);
});

//handle reset
$('#acc_reset').click(resetFields);
});

//wait and open headline
load();

</script>	




JS3
( function($){

	EP.Portlets.StoryMaster = function(config) {
		this.__init(config);
	};

	var proto = EP.Portlets.StoryMaster.prototype;

	proto.__init = function(config) {
		
		this.scheduleVO = {};
		
		this.storyAction;

		//-- if config available, set from config
		if(config) {
			this.storyHeadline = "";
			this.id = config.id;
			this.articleId = config.masterPageId;
			this.oldArticleId = config.oldPageId;
			this.type = config.pageType;
			this.oldType = config.oldPageType;
			this.pageTypeId = config.pageTypeId;
			this.storyLayoutId = 0;
			this.siteId = config.siteId;
			this.publishBy = config.publishDate;
			this.unpublishBy = config.unPublishDate;
			this.defaultTemplateCategoryId = config.defCategoryId;
			this.layoutId = config.layoutId;
			this.scheduleVO.publishBy = config.publishDate;
			this.scheduleVO.oldPublishBy = "None";
			this.scheduleVO.unPublishBy = config.unPublishDate;
			this.scheduleVO.oldUnPublishBy = "None";
			this.formAction = config.formAction;
			this.storyVersions = config.storyVersions;
			this.currentVersion = config.currentVersion;
			this.storyTransitionStates = config.storyTransitionStates;
			this.storyStatus = config.storyStatus;
			this.defaultArticleRequestId = config.defaultArticleRequestId;
			this.lock = config.lock;
			this.editable = config.editable;
			this.sharedByReference = config.sharedByReference;
			this.htmlPageTitle = config.htmlPageTitle;
			this.dashboardUrl = config.dashboardUrl;
			this.operation = config.operation;
			this.siteTimeZone = config.siteTimeZone;
			this.lockStoryMasterToTop = config.lockStoryMasterToTop;
			this.sourceId = config.sourceId;
			this.defaultPageFlag = config.defaultPageFlag;
			document.title = config.htmlPageTitle;
		}

		this.UI = {}; //-- UI object
	};
		
	proto.read = function() {
	};
		
	proto.write = function() {
		
	};

	proto.toJSON  = function () {
		var jsonObj = {};
		
		for( x in this ){
			if( x != 'UI' && x != 'expireScheduleEditor' && x != 'publishScheduleEditor'){
				jsonObj[x] = this[x];
			}
		}

		return jsonObj;
	};

	proto.render = function() {
		var me = this;

		//-- Lock Story Master for to top (fixed position)
		if( this.lockStoryMasterToTop ) {
			$('html').addClass('fixed-master');
		}

		//-- UI Nodes; default jQuery
		me.UI.nodes = {};
		var _nodes = me.UI.nodes;
		
		_nodes.storyMaster = { $ : jQuery('.storyallmaster-portlet') };
		_nodes.btnLock = { $ : _nodes.storyMaster.$.find('#btn-lock') };
		_nodes.portletSettings = { $ : _nodes.storyMaster.$.find('.portlet-settings') };
		_nodes.btnCopyStory = { $ : _nodes.storyMaster.$.find('.btn[name="copy-story"]') };
		_nodes.btnDeleteStory = { $ : _nodes.storyMaster.$.find('.btn[name="delete-story"]') };
		_nodes.userLockStatus = { $ : _nodes.storyMaster.$.find('.user-lock-status div') };
		_nodes.btnPreview = { $ : _nodes.portletSettings.$.find('.btn[name="preview"]') };

		//-- copy the active story to a new tab
		_nodes.btnCopyStory.$.bind('click', function(){
			window.open(window.location.pathname + '?type=' + me.pageTypeId + '&storyId='+ me.articleId + '&isCopy=true' + '&pageTitle=' + 'Copy of ' + me.htmlPageTitle, //-- copy story URL
				'Copy_of_Story_' + Math.floor( 1000 * Math.random() ) //-- window name
			);
		});
		
		this.updateLock(me, _nodes);
		
		_nodes.btnLock.$.bind('click', function(){
			var $this = $(this);
			var oldLock = me.lock;
			var msgChange = '';
			me.checkLock( me );
			if( (me.lock.locked != oldLock.locked) || (me.lock.lockId != oldLock.lockId) || (me.lock.lockBy != oldLock.lockBy) ) {
				msgChange = '<strong>The page lock has been changed by others.</strong><br/><br/>';
				me.updateLock(me, _nodes);
			}
			if($this.hasClass('unlock') || $this.hasClass('by-user')){
				me.UI.pageLockingModal.ask({
					msg : $this.hasClass('by-user') ? msgChange+'This Page was ' + _nodes.userLockStatus.$.html() + '.<br/> Do you want to acquire a lock for this story?' : msgChange+'Do you want to acquire a lock for this story?',
					box : {
						text : 'Keep my changes'
					},
					cancel : {
						text : 'Cancel'
					},
					proceed : {
						text : 'Acquire Lock',
						action : function(checkFlag){
							//direct acquire lock and ignore others modification.
							var url = '/story-wizard-portlet/restful/acquireLock?articleId='+me.articleId+'&asAdmin='+$this.hasClass('by-user')+'&userId='+userId+'&groupId='+groupId;
							EP.io.request(url, {
								data : {
									val : {
										contentType : 'CREATESTORY',
										subType : 'acquireLock'
									}
								},
								dataType : 'json',
								method : 'GET',
								on : {
									success : function() {
										var obj = this.get('responseData');	
										me.lock = obj.lock;
										me.updateLock(me, _nodes);
										if(obj.success) {
											EP.Util.success.alert(obj.message||"Lock acquired.");
											if(!checkFlag) {
												//check box not checked, means reload page to fetch updated content
												window.location.reload();
											}
										} else {
											EP.Util.error.alert(obj.message||"Error acquiring lock.");
										}
									}
								}
							});
						}
					},
				});
			} else {
				me.UI.pageLockingModal.ask({
					msg : msgChange+'Do you want to release the lock on this story?',
					cancel : {
						text : 'Cancel'
					},
					proceed : {
						text : 'Release Lock',
						action : function(){
							var url = '/story-wizard-portlet/restful/releaseLock?lockId='+me.lock.lockId+'&articleId='+me.articleId+'&userId='+userId+'&groupId='+groupId;
							EP.io.request(url, {
								data : {
									val : {
										contentType : 'CREATESTORY',
										subType : 'releaseLock'
									}
								},
								dataType : 'json',
								method : 'GET',
								on : {
									success : function() {
										var obj = this.get('responseData');	
										me.lock = obj.lock;
										me.updateLock(me, _nodes);
										if(obj.success) {
											EP.Util.success.alert(obj.message||"Lock released.");
										} else {
											EP.Util.error.alert(obj.message||"Error releasing lock.");
										}
									}
								}
							});
						}
					},
				});
			}
			$this.blur();
		}).hover( function(){
			if( _nodes.userLockStatus.$.queue('fx').length < 1 ){
				_nodes.userLockStatus.$.effect( 'slide', {
					direction : 'left',
					mode : 'show'
				}, 500 );
			} else {
				_nodes.userLockStatus.$.dequeue('fx').removeAttr('style');

			}
		}, function(){
			if( _nodes.userLockStatus.$.queue('fx').length < 1 ){
				_nodes.userLockStatus.$.effect( 'slide', {
					direction : 'left',
					mode : 'hide'
				}, 500 );
			} else {
				_nodes.userLockStatus.$.dequeue('fx').removeAttr('style');
			}
		});

		window.onbeforeunload = function(){
			// Story.js will call onbeforeunload first
			if (me.storyStatus != 'new') {
				var $this = _nodes.btnLock.$;
				me.checkLock( me );
				me.updateLock(me, _nodes);
				if(!$this.hasClass('unlock') && !$this.hasClass('by-user')) {
					var url = '/story-wizard-portlet/restful/releaseLock?lockId='+me.lock.lockId+'&articleId='+me.articleId+'&userId='+userId+'&groupId='+groupId;
					EP.io.request(url, {
						data : {
							val : {
								contentType : 'CREATESTORY',
								subType : 'releaseLock'
							}
						},
						dataType : 'json',
						method : 'GET',
						sync: true,
						on : {success : function() {}}
					});
				}
				return;
			}
		};
		
		_nodes.btnPreview.$.live('click', function(){
			var $this = _nodes.btnPreview.$;
			
			if( !$this.attr('disabled') ){
				
				var checkedDefaultFlag = document.getElementById('page-default').checked;
				if( !me.defaultPageFlag && (checkedDefaultFlag == true) ) {
					// TPRA-2434   //sync save
					__WS_StoryMaster.save( true );
				}
				window.open( $this.attr('value'), "PREVIEW");
			}
		});

		//-- UI setup
		me.UI.updateState = function(){
			//-- articleId means published
			if( me.articleId ){
				//_nodes.btnPreview.$.show();
				//_nodes.btnCopyStory.$.show();
				//_nodes.btnDeleteStory.$.show();
				EP.Util.disableToggle( _nodes.btnPreview.$, false );
				EP.Util.disableToggle( _nodes.btnCopyStory.$, false );
				EP.Util.disableToggle( _nodes.btnDeleteStory.$, false );
				_nodes.storyMaster.$.addClass('lockable');
			} else {
				//_nodes.btnPreview.$.hide();
				//_nodes.btnCopyStory.$.hide();
				//_nodes.btnDeleteStory.$.hide();
				EP.Util.disableToggle( _nodes.btnPreview.$, true );
				EP.Util.disableToggle( _nodes.btnCopyStory.$, true );
				EP.Util.disableToggle( _nodes.btnDeleteStory.$, true );
				_nodes.storyMaster.$.removeClass('lockable');
			}
		};
		
		//-- manage expansion of settings hanging tab
		me.UI.updateOverlayPush = function(){
			jQuery('#column-3').css(
				'padding-top',
				_nodes.portletSettings.$.height()
			);
		};

		//-- format incoming version values before adding to UI
		me.formatVersionText = function( value ){

			var splitStr = value.split(' - ');

			var newValue = '<span class="version">'
				+ splitStr[0].substring(8)
				+ '</span><span class="timestamp">'
				+ splitStr[1]
				+ '</span><span class="author">'
				+ splitStr[2] + '</span>';

			return newValue;
		};
		
		//-- get version from value
		me.getVersion = function( value ){

			var splitStr = value.split(' - ');
			var version = splitStr[0].substring(8);

			return version;
		};

		jQuery('div#storyVersion').show();
		if (me.storyVersions && me.storyVersions.length > 0) {
			jQuery.each(me.storyVersions, function(index, value){
				jQuery('#story-version-list').append('<li value="' + me.getVersion( value) + '">' + me.formatVersionText( value ) + '</li>');
			});
			$('#selectedStoryVersion').html( me.currentVersion );
			$('#story-version-list').find('li[value="' + me.currentVersion + '"]').addClass('active');
		} else {
			jQuery('#story-version-list').append('<li value="-1"><span class="version">No saved versions</span></li>');
			$('#story-version-list').find('li[value="-1"]').addClass('active');
		}
		
		if (me.storyTransitionStates) {
			jQuery.each(me.storyTransitionStates, function(key, value){
				jQuery('#storyStatesList').append( '<li id="' + value.transitionValue + '">' + value.transitionLabel +  '</li>' );
			});
		}
		
		/**** EVENTS ****/
		
		//-- show available versions
		$('.btn[name="show-version-list"]').bind('click', function(e){
			$(this).blur();
			$('#story-version-list').addClass('active');
			$('body').bind('click', function(e){
				if( $( e.target ).get(0) != $('#story-version-list').get(0) ){
					$('#story-version-list').removeClass('active');
					$(this).unbind('click');
				}
			});
			e.stopPropagation();
		});

		//-- on list click, select appropriate version
		$('#story-version-list').find('li').live('click', function(i){
			var $this = $(this);
			var value = this.getAttribute('value');
//			var optionVer = $('#storyVersions').find('option');
//			var selectedVer = optionVer.filter('option:selected');
			if( $('#story-version-list li').length > 1 ){
				me.UI.confirmationModal.ask({
					msg : 'Changing a story version will delete any unsaved edits',
					cancel : {
						text : 'Cancel'
					},
					proceed : {
						text : 'Change Version',
						action : function(){
							$this.siblings('li').removeClass('active').end();
							 AUI().use(
								'ep-io-request',
								function(A) {
									var url = '/story-wizard-portlet/restful/storyversionget?storyId='+me.articleId+'&storyVersionNumber='+value+'&type='+me.pageTypeId+'&userId='+userId+'&groupId='+groupId;
									EP.io.request(url, {
										dataType : 'json',
										
										data : {
											val : {
												contentType : 'CREATESTORY',
												subType : 'CHANGE_VERSION',
												groupId : groupId,
												type : me.pageTypeId,
												storyId : me.articleId,
												storyVersionNumber : value,
												userId : userId
											}	
										},
										
										
										method : 'GET',
										on : {
											success : function() {
												var obj = this.get('responseData');	
												obj.storyVO.settingsVO = {};
												obj.storyVO.settingsVO.version = value;
												__WS_StoryMaster.refreshVersionData({storyAbstract : obj.storyVO.storyAbstract,
													 storyBody : obj.storyVO.storyBody,
													 version : value,
													 updateVersionedFieldsData : true});
												me.currentVersion = value;
												
												$('#story-version-list').find('li[value="' + value + '"]').addClass('active');
												$('#selectedStoryVersion').html( value );
											}
										}
									});
								});
							$('#storyVersions').val( value ).trigger('change');
							$('#story-version-list').removeClass('active');
						}
					},
				});
			}
		});

		//-- show page status options; hide on click outside container
		jQuery('#statusEdit').click( function(e) {
			$(this).blur();
			jQuery('#storyStatesList').show();
			$('body').bind('click', function(e){
				if( $( e.target ).get(0) != $('#storyStatesList').get(0) ){
					jQuery('#storyStatesList').hide();
					$(this).unbind('click');
				}
			});
			e.stopPropagation();
		});
		
		if (me.sharedByReference) {
			$('#update-btn').show();
//			$('span#unpublish_schedule').disable();
//			$('#storyVersion')
		} 
		if (me.storyStatus == 'new') {
			$('#save-btn').show();
			$('#publish-btn').show();
			$('span#unpublish_schedule').hide();
		} else if (me.storyStatus == 'draft') {
			$('#save-btn').show();
			$('#publish-btn').show();
			$('span#unpublish_schedule').hide();
		} else {
			$('span#unpublish_schedule').toggle(true);
			$('#save-btn').show();
			if (me.storyStatus == 'approved') {
				$('#publish-btn').hide();
				if(me.scheduleVO.unPublishBy == 'None') {
					$('#expire-btn').show();
				} else {
					$('#expire-btn').hide();
				}
				$('#publish_schedule').hide();
				$('#unpublish_schedule').show();
			} else if (me.storyStatus == 'expired')	{
				if(me.scheduleVO.publishBy == 'None') {
					$('#publish-btn').show();
				} else {
					$('#publish-btn').hide();
				}
				$('#expire-btn').hide();
				$('#publish_schedule').show();
				$('#unpublish_schedule').hide();
			} else if (me.storyStatus == 'Deleted')	{
				$('#publish-btn').hide();
				$('#expire-btn').hide();
				$('#publish_schedule').hide();
				$('#unpublish_schedule').hide();
			} else {
				$('#publish-btn').show();
				$('#expire-btn').hide();
				$('#publish_schedule').show();
				$('#unpublish_schedule').show();
			}		
			jQuery('#statusEdit').toggle(true);
		}
		
		$('html').toggleClass('has-pub-schedule', $('#publish_schedule:visible').length > 0);
		$('html').toggleClass('has-unpub-schedule', $('#unpublish_schedule:visible').length > 0);

		$('#storyStatesList li').live('click', function(){
			if(!me.acquireLock(me,_nodes)) {
				var $this = $(this);			
				var afterConfirm = function(){
					var currentStatus = me.storyStatus;
					me.oldStoryStatus = currentStatus;
					me.storyStatus = $this.attr('id');
					if (me.storyStatus == 'approved') {
						me.storyAction = 'Publish';
						me.scheduleVO.publishBy = 'Immediately';
						me.scheduleVO.unPublishBy = 'None';
					} else if (me.storyStatus == 'expired')	{
						me.storyAction = 'UnPublish';
						me.scheduleVO.publishBy = 'None';
						me.scheduleVO.unPublishBy = 'Immediately';
					} else {
						me.storyAction = '';
						me.scheduleVO.publishBy = 'None';
						me.scheduleVO.unPublishBy = 'None';
					}
				    me.stateChangeRequest = true;
					jQuery('#storyStatesList').toggle(false);
					me.checkLock( me );
					me.updateLock(me, _nodes);
					__WS_StoryMaster.save();
					me.stateChangeRequest = false;
				};
				var changeStatus = $this.attr('id');
				if(changeStatus == 'Purge')
				{
				    var cancel_btn = me.UI.confirmPurgeModal.get().bodyNode.one('.btn[name="cancel"]');
					cancel_btn.setStyle('marginLeft', '410px');
				    me.UI.confirmPurgeModal.ask({
						msg :'<b>Permanently Remove?</b><br/> Once you Purge content, it cannot be restored.',
						cancel : {
							text : 'Cancel'
						},
						proceed : {
							text : 'Purge',
							action : function(){
								 afterConfirm();
							}
						},
					});	
				
				} else {
				  afterConfirm();
				}
			}
		});
		//-- render
		me.UI.updateState();
		
		$('#btn_publish').click(function() {
			if(!me.acquireLock(me,_nodes)) {
				var currentStatus = me.storyStatus;
				me.oldStoryStatus = currentStatus;
				me.storyStatus = 'approved';
				me.storyAction = 'Publish';
				me.scheduleVO.oldPublishBy = me.scheduleVO.publishBy;
				me.scheduleVO.oldUnPublishBy = me.scheduleVO.unPublishBy;
				me.scheduleVO.publishBy = 'Immediately';
				me.scheduleVO.unPublishBy = me.scheduleVO.oldUnPublishBy;
				var successful = EP.Controllers[masterAttrName].save();
				if(!successful) {
					// if front end validate failed, roll back here.
					me.storyStatus = me.oldStoryStatus;
					me.scheduleVO.publishBy = me.scheduleVO.oldPublishBy;
					me.scheduleVO.unPublishBy = me.scheduleVO.oldUnPublishBy;
				}
			}
		});
		
		$('#btn_save').click(function() {
			if(!me.acquireLock(me,_nodes)) {
				var currentStatus = me.storyStatus;
				me.oldStoryStatus = currentStatus;
				me.storyStatus = 'draft';
				me.storyAction = 'Saved';
				var successful = EP.Controllers[masterAttrName].save();
				if(!successful) {
					// if front end validate failed, roll back here.
					me.storyStatus = me.oldStoryStatus;
				}
			}
		});
		
		$('#btn_expire').click(function() {
			if(!me.acquireLock(me,_nodes)) {
				var currentStatus = me.storyStatus;
				me.oldStoryStatus = currentStatus;
				me.storyStatus = 'expired';
				me.storyAction = 'UnPublish';
				me.scheduleVO.oldPublishBy = me.scheduleVO.publishBy;
				me.scheduleVO.oldUnPublishBy = me.scheduleVO.unPublishBy;
				me.scheduleVO.publishBy = 'None';
				me.scheduleVO.unPublishBy = 'Immediately';
				var successful = EP.Controllers[masterAttrName].save();
				if(!successful) {
					// if front end validate failed, roll back here.
					me.storyStatus = me.oldStoryStatus;
					me.scheduleVO.publishBy = me.scheduleVO.oldPublishBy;
					me.scheduleVO.unPublishBy = me.scheduleVO.oldUnPublishBy;
				}
			}
		});
				
		$('#btn_update').click(function() {
			if(!me.acquireLock(me,_nodes)) {
				var currentStatus = me.storyStatus;
				me.oldStoryStatus = currentStatus;
				me.storyAction = 'Update';
				var successful = EP.Controllers[masterAttrName].save();
				if(!successful) {
					// if front end validate failed, roll back here.
					me.storyStatus = me.oldStoryStatus;
				}
			}
		});
		
		var storyMasterSchedule = null;
		var storyMasterUnpublishSchedule = null;

		//-- AUI
		AUI().use('ep-dialog-confirmation', function(A){

			me.UI.confirmationModal = new EP.Components.confirmationDialog({
				dialog : {
					dialogOptions : {
						title : 'Version Change'
					}
				}
			});

			me.UI.rejectShareModal = new EP.Components.confirmationDialog({
				dialog : {
					dialogOptions : {
						title : 'Reject Share'
					}
				}
			});
			
			me.UI.releaseLockModal = new EP.Components.confirmationDialog({
				dialog : {
					dialogOptions : {
						title : 'Release Lock'
					}
				}
			});
			
			me.UI.pageLockingModal = new EP.Components.confirmationDialog({
				dialog : {
					dialogOptions : {
						title : 'Page Locking'
					}
				}
			});
			
			me.UI.confirmPurgeModal = new EP.Components.confirmationDialog({
				dialog : {
					dialogOptions : {
						title : 'Purge content'
					}
				}
			});
		});
		
		$(document).ready(function(){
			me.publishScheduleEditor = $('StoryMaster_schedule').scheduleEditor({
				defaultValue: me.scheduleVO.publishBy,
				hasImmediately: false,
				hasNone: true,
				siteTimeZone: me.siteTimeZone,
				hasNone: true,
				selector:'StoryMaster_schedule',
				onFinishEdit: function(value) {
					if(value['schedule'] == 'None') {
						me.scheduleVO.publishBy = 'None';
					} else if(value['schedule'] == 'Immediately') {
						me.scheduleVO.publishBy = 'Immediately';
					} else {
						me.scheduleVO.publishBy = value['scheduleMonth']
							+'/'+ value['scheduleDay']
							+'/'+ value['scheduleYear']
							+' '+ value['scheduleHour']
							+':'+ value['scheduleMinute']
							+' '+ value['ampm']
							+' '+ value['timezone'];
							$('#publish-btn').hide();
					}
					
					if (me.storyStatus == 'new') {
						$('#expire-btn').hide();
						if(me.scheduleVO.publishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					} else if (me.storyStatus == 'draft') {
						$('#expire-btn').hide();
						if(me.scheduleVO.publishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					} else if (me.storyStatus == 'approved') {
						$('#publish-btn').hide();
						if(me.scheduleVO.unPublishBy == 'None') {
							$('#expire-btn').show();
						} else {
							$('#expire-btn').hide();
						}
					} else if (me.storyStatus == 'expired') {
						$('#expire-btn').hide();
						if (me.scheduleVO.publishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					} else {
						$('#expire-btn').hide();
						if (me.scheduleVO.publishBy == 'None' 
							&& me.scheduleVO.unPublishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					}
					
				},
				onSaveCheck: function(value, date) {
					var result = value;
					if (storyMasterUnpublishSchedule != null &&
						date < storyMasterUnpublishSchedule) {
					result += "the publish date is before the unpublish date\n";
					} else {
						storyMasterSchedule = date;
					}
					return result;
				}
			});
				
			me.expireScheduleEditor  = $('StoryMaster_unpublish_schedule').scheduleEditor({
				defaultValue: me.scheduleVO.unPublishBy,
				hasImmediately: false,
				hasNone: true,
				siteTimeZone: me.siteTimeZone,
				selector: 'StoryMaster_unpublish_schedule',
				disabled: me.sharedByReference,
				onFinishEdit: function(value){
					if(value['schedule'] == 'None') {
						me.scheduleVO.unPublishBy = 'None';
					} else if(value['schedule'] == 'Immediately') {
						me.scheduleVO.unPublishBy = 'Immediately';
					} else {
						me.scheduleVO.unPublishBy = value['scheduleMonth']
							+'/'+ value['scheduleDay']
							+'/'+ value['scheduleYear']
							+' '+ value['scheduleHour']
							+':'+ value['scheduleMinute']
							+' '+ value['ampm']
							+' '+ value['timezone'];
					}
					
					if (me.storyStatus == 'new') {
						$('#expire-btn').hide();
						if(me.scheduleVO.publishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					} else if (me.storyStatus == 'draft') {
						$('#expire-btn').hide();
						if(me.scheduleVO.publishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					} else if (me.storyStatus == 'approved') {
						$('#publish-btn').hide();
						if(me.scheduleVO.unPublishBy == 'None') {
							$('#expire-btn').show();
						} else {
							$('#expire-btn').hide();
						}
					} else if (me.storyStatus == 'expired') {
						$('#expire-btn').hide();
						if (me.scheduleVO.publishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					} else {
						$('#expire-btn').hide();
						if (me.scheduleVO.publishBy == 'None' 
							&& me.scheduleVO.unPublishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					}
					
				},
				onSaveCheck: function(value, date) {
					var result = value;
					if (storyMasterSchedule != null &&
						date < storyMasterSchedule) {
						result += "the publish date is before the unpublish date\n";
					} else {
						storyMasterUnpublishSchedule = date;
					}
					return result;
				},
				changeExpirationDate:function(date){
					var tmp = date;
					this.contents_new['schedule'] = 'Scheduled';
					this.contents_new['scheduleMonth'] = tmp.substring(0, tmp.indexOf("/"));
					tmp = tmp.substring(tmp.indexOf("/") + 1);
					this.contents_new['scheduleDay'] = tmp.substring(0, tmp.indexOf("/"));
					tmp = tmp.substring(tmp.indexOf("/") + 1);
					this.contents_new['scheduleYear'] = tmp.substring(0, tmp.indexOf(" "));
					tmp = tmp.substring(tmp.indexOf(" ") + 1);
					this.contents_new['scheduleHour'] = tmp.substring(0, tmp.indexOf(":"));
					tmp = tmp.substring(tmp.indexOf(":") + 1);
					this.contents_new['scheduleMinute'] = tmp.substring(0, tmp.indexOf(" "));
					tmp = tmp.substring(tmp.indexOf(" ") + 1);
					this.contents_new['ampm'] = tmp.substring(0, tmp.indexOf(" "));
					tmp = tmp.substring(tmp.indexOf(" ") + 1);
					this.contents_new['timezone'] = tmp;
				}
			});
		});
		
		$(document).ready(function(){
			if (!me.editable) {
				jQuery('.portlet-content-container > .portlet-body').each( function(){
					EP.Util.disableOverlay( this );
				});
				EP.Util.disableOverlay( jQuery('.storyallmaster-portlet .portlet-content-container .portlet-body').get(0), false);
			} else {
				// overlay content to the locked page by others or unlocked, until acquire lock from others
				if(me.lock && me.lock.locked) {
					jQuery('.portlet-content-container > .portlet-body').each( function(){
						EP.Util.disableOverlay( this );
				    });
					EP.Util.disableOverlay( jQuery('.storyallmaster-portlet .portlet-content-container .portlet-body').get(0), false);
					EP.Util.disableToggle( $('#btn_save'), true );
					EP.Util.disableToggle( $('#btn_publish'), true );
					EP.Util.disableToggle( $('#btn_expire'), true );
					jQuery('#statusEdit').toggle(false);
				} else if(me.lock && me.lock.lockId) {
					jQuery('.portlet-content-container > .portlet-body').each( function(){
						EP.Util.disableOverlay( this, false );
					});
					EP.Util.disableToggle( $('#btn_save'), false );
					EP.Util.disableToggle( $('#btn_publish'), false );
					EP.Util.disableToggle( $('#btn_expire'), false );
					jQuery('#statusEdit').toggle(true);
				} else {
					if(me.storyStatus != 'new') {
						jQuery('.portlet-content-container > .portlet-body').each( function(){
							EP.Util.disableOverlay( this );
					    });
						EP.Util.disableOverlay( jQuery('.storyallmaster-portlet .portlet-content-container .portlet-body').get(0), false);
						EP.Util.disableToggle( $('#btn_save'), true );
						EP.Util.disableToggle( $('#btn_publish'), true );
						EP.Util.disableToggle( $('#btn_expire'), true );
						jQuery('#statusEdit').toggle(false);
					}
				}
			}
			if (me.sharedByReference) {
				jQuery('#wrapper').addClass('isShared');
				EP.Util.disableOverlay( jQuery('.category-portlet .portlet-content-container .portlet-body').get(0), false);
				EP.Util.disableOverlay( jQuery('.topics-portlet .portlet-content-container .portlet-body').get(0), false);
				jQuery('#statusEdit').hide();
				
//				$('#unpublish_schedule').hide();
//				$('#publish_schedule').hide();
				$('#publish-btn').hide();
				$('#expire-btn').hide();
				$('#save-btn').hide();
				$('#update-btn').show();
				$('#statusEdit').hide();
				
			}
		});
		
		$('#reject-story').click(function(){
			me.UI.rejectShareModal.ask({
				msg : 'Are you sure you want to reject? Once Rejected, page(s) cannot be restored.',
				cancel : {
					text : 'Cancel'
				},
				proceed : {
					text : 'Okay',
					action : function(){
						var url = '/story-wizard-portlet/restful/rejectShare?storyId='+me.articleId+'&userId='+userId+'&groupId='+groupId;
						EP.io.request(url, {
							data : {
								val : {
									contentType : 'CREATESTORY',
									subType : 'rejectShare'
								}
							},
							dataType : 'json',
							method : 'GET',
							on : {
								success : function() {
									var obj = this.get('responseData');	
									if(obj.success) {
										window.close();
									} else {
										EP.Util.error.alert(obj.message||"Error Rejecting Shared Page");
									}
								}
							}
						});
					}
				},
			});
		});
				
		_nodes.btnDeleteStory.$.bind('click', function(){
			me.UI.rejectShareModal.ask({
				msg : '<b>Permanently Remove?</b><br/> Once you Delete content, it cannot be restored.',
				cancel : {
					text : 'Cancel'
				},
				proceed : {
					text : 'Okay',
					action : function(){
						var url = '/story-wizard-portlet/restful/deleteStory?articleId='+me.articleId+'&userId='+userId+'&groupId='+groupId;
						EP.io.request(url, {
							data : {
								val : {	}
							},
							dataType : 'json',
							method : 'GET',
							on : {
								success : function() {
									var obj = this.get('responseData');	
									if(obj.success) {
										window.close();
									} else {
										EP.Util.error.alert(obj.message||"Error Deleting Story.");
									}
								}
							}
						});
					}
				}
			});
		});
	};	
	
	proto.preSave = function(data) {
		this.storyHeadline = data.storyVO.headline;
		if(data.storyVO.settingsVO.selectedContentType){
			this.type = data.storyVO.settingsVO.selectedContentType;
		}
		if(data.storyVO.settingsVO.contentType) {
			if(data.storyVO.settingsVO.contentType == "Gallery") {
				this.type = "gallery";
			}else if(data.storyVO.settingsVO.contentType == "ListGallery") {
				this.type = "list-gallery";
			}
		}
		
		return data;
	};
		
	proto.postSave = function(data) {
		var me = this;
		var message = '';
		var internalUrl = '';
		if(data.storyResult && data.storyResult.success != null) {
			if(data.storyResult.success == true) {
				if(data.storyResult.articleId) {
					//message = data.storyResult.response;
					switch(data.storyResult.storyStatus){
						case 'approved' :
							if ( me.sharedByReference )
								statusDisplayMessage = 'Has been <span style="background-color: #349405; color: #FFFFFF; font-weight: bold; padding: 3px 6px;">Updated</span>';
							else
								statusDisplayMessage = 'Has been <span style="background-color: #349405; color: #FFFFFF; font-weight: bold; padding: 3px 6px;">Published</span>';
							break;
						case 'draft' :
							statusDisplayMessage = 'Has been saved as a <span style="background-color: #3F3E3D; color: #FFFFFF; font-weight: bold; padding: 3px 6px;">Draft</span>';
							break;
						case 'expired' :
							statusDisplayMessage = 'Has been <span style="background-color: #8B8B8B; color: #FFFFFF; font-weight: bold; padding: 3px 6px;">Expired</span>';
							break;
						default :
							statusDisplayMessage = 'Has been saved as a <span style="background-color: #3F3E3D; color: #FFFFFF; font-weight: bold; padding: 3px 6px;">'+data.storyResult.storyStatus+'</span>';
					}
					
					message = message
						+ '<div style="margin-bottom: 10px;"><span style="font-weight: bold; font-size: 14px;">Story Headline : </span>' + data.storyResult.headline + '</div>'
						+ '<div style="margin-bottom: 10px;"><span style="font-weight: bold; font-size: 14px;">Story Page ID : </span>' + data.storyResult.articleId + '</div>'
						+ '<div style="margin-bottom: 10px;">' + statusDisplayMessage + '</div>';
				}
				
				if ( me.sharedByReference ) {
					EP.Util.success.alert(message);
					return;
				}
				
				// reset default article request flag
				this.defaultArticleRequestId = null;
				
				if(data.storyResult.unpublishBy) {
					$('#StoryMaster_unpublish_schedule').text(data.storyResult.unpublishBy);
					this.expireScheduleEditor.changeExpirationDate.call(this.expireScheduleEditor,data.storyResult.unpublishBy);
				}
				
				if(data.storyResult.defaultPageFlag) {
					this.defaultPageFlag = data.storyResult.defaultPageFlag;
				}
				
				if (this.storyVO.settingsVO.sourceId != null) {
					this.sourceId = this.storyVO.settingsVO.sourceId;
				}
				else if(data.storyResult.sourceId) {
					this.sourceId = data.storyResult.sourceId;
				}
				
				if(data.storyResult.url) {
					internalUrl = data.storyResult.url;
					jQuery('#storyall-master_url').html(internalUrl);
				}
				
				//if(data.storyResult.layoutPath) {
				//	jQuery('button[name="preview"]').attr('value',data.storyResult.layoutPath);
				//}
				
				if(data.storyResult.articleId) {
					jQuery('button[name="preview"]').attr('value', viewNonstoryUrl + data.storyResult.urlTitle  + '?workflowAssetPreview=true&version=' + data.storyResult.currentVersion);
				}
				
				if (data.storyResult.storyVersions)	{
					jQuery('div#storyVersion').show();
					jQuery('#story-version-list').find('li').remove().end();
					jQuery.each(data.storyResult.storyVersions, function(index, value){
						jQuery('#story-version-list').append('<li value="' + me.getVersion( value) + '">' + me.formatVersionText( value ) + '</li>');
					});
					$('#selectedStoryVersion').html(data.storyResult.currentVersion );
					$('#story-version-list').find('li[value="' +data.storyResult.currentVersion + '"]').addClass('active');
				}
				
				if (data.storyResult.articleId) {
					this.articleId = data.storyResult.articleId;
					jQuery('#story_page_id').html(this.articleId);
				}
				
				if(data.storyResult.layoutId) {
					this.storyLayoutId = data.storyResult.layoutId;
				}
				
				if(data.storyResult.siteId) {
					this.siteId = data.storyResult.siteId;
				}
				
				if(data.storyResult.publishBy) {
					this.publishBy = data.storyResult.publishBy;
					this.scheduleVO.publishBy = data.storyResult.publishBy;
				}
							
				if(data.storyResult.unpublishBy) {
					this.unpublishBy = data.storyResult.unpublishBy;
					this.scheduleVO.unPublishBy = data.storyResult.unpublishBy;
				}
				
				if(data.storyResult.storyAction) {
					this.storyAction = data.storyResult.storyAction;
				}
				
				if(data.storyResult.lockVO) {
					this.lock = data.storyResult.lockVO;
					this.updateLock(this, this.UI.nodes);
				}
				if(data.storyResult.description) {
					$('#description').val(data.storyResult.description);
				}
				if(data.storyResult.shortHeadline) {
					$('#input_short-headline').val(data.storyResult.shortHeadline);
				}
				if(data.storyResult.urlTitle) {
					$('#file-name').val(data.storyResult.urlTitle);
				}
				if(data.storyResult.title) {
					$('#page-name').val(data.storyResult.title);
				}
				if(data.storyResult.title) {
					$('#page-title').val(data.storyResult.title);
				}
				this.storyProxySave();
				if (data.storyResult.storyStatus) {
					// handle status display
					var statusDisplay = data.storyResult.storyStatus;
					if (data.storyResult.storyStatus == 'approved') {
						statusDisplay = 'published';
					} else if (data.storyResult.storyStatus == 'expired') {
						statusDisplay = 'expired';
					}
					
					$('#storyStatusLabel').text( statusDisplay.toUpperCase());
					$('#save-btn').show();
					$('span#unpublish_schedule').toggle(true);
					me.storyStatus = data.storyResult.storyStatus;
					if (me.storyStatus == 'approved') {
						$('#publish-btn').hide();
						if(me.scheduleVO.unPublishBy == 'None') {
							$('#expire-btn').show();
						} else {
							$('#expire-btn').hide();
						}
						$('#publish_schedule').hide();
						$('#unpublish_schedule').show();
					} else if (me.storyStatus == 'expired')	{
						if(me.scheduleVO.publishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
						$('#expire-btn').hide();
						$('#publish_schedule').show();
						$('#unpublish_schedule').hide();
					} else if (me.storyStatus == 'Deleted')	{
						$('#publish-btn').hide();
						$('#expire-btn').hide();
						$('#publish_schedule').hide();
						$('#unpublish_schedule').hide();
					} else {
						$('#publish-btn').show();
						$('#expire-btn').hide();
						$('#publish_schedule').show();
						$('#unpublish_schedule').show();
					}
					
					jQuery('#statusEdit').toggle(true);

					if ((me.oldStoryStatus == 'new' || me.pageTypeId != data.storyResult.type)
						&& (typeof window.history.pushState == 'function')) {
						window.history.pushState("Updating page URL after new save.",
							me.htmlPageTitle, viewStoryWizardUrl + data.storyResult.articleId + '&type=' + data.storyResult.type);
						this.pageTypeId = data.storyResult.type;
					}
					
					// update content type for fxd gallery after new save.
					var hasGalleryDropDown = document.getElementById('select_story_content_type');
					if(me.oldStoryStatus == 'new' && hasGalleryDropDown && (data.storyResult.type == "gallery" || data.storyResult.type == "list-gallery")) {
						if(data.storyResult.type == "gallery") {
							var contentType = "<span class=\"aui-field-element\" id=\"story_content_type\">Gallery</span>";
							jQuery('#select_story_content_type').replaceWith(contentType);
						}else if(data.storyResult.type == "list-gallery") {
							var contentType = "<span class=\"aui-field-element\" id=\"story_content_type\">ListGallery</span>";
							jQuery('#select_story_content_type').replaceWith(contentType);
						}
					}
				}
				
				jQuery('#statusEdit').show();
				
				if( data.storyResult.lastEditedDateFormatted) {
					$('#storyLastEditDateLabel').text( data.storyResult.lastEditedDateFormatted);
				}
				
				if (data.storyResult.storyTransitionStates) {
					 jQuery('#storyStatesList').find('li').remove().end();
					 jQuery.each(data.storyResult.storyTransitionStates, function(key, value){
						jQuery('#storyStatesList').append( '<li id="' + value.transitionValue + '">' + value.transitionLabel +  '</li>' );
					 });

				}
				
				// Update the distributions
				me.writeDistributionsToPage(data.storyResult.distributionStatus);
				
				//update settings version data
				__WS_StoryMaster.refreshVersionData({version : data.storyResult.currentVersion,
					 updateVersionedFieldsData : false});
				me.currentVersion = data.storyResult.currentVersion;
			
				if (isWorkflowTurnedOn && data.storyResult.storyStatus == 'draft') {
					location.href = viewStoryWizardUrl + data.storyResult.articleId + '&type=' + me.pageTypeId;
				}
								
				this.operation = 'EDIT';
				//alert(message);
				EP.Util.success.alert(message);
			} else {
				var message = '';
				if(data.storyResult.response) {
					console.log('in postSave failure');
					message = message +  data.storyResult.response;
				}
				if(me.storyStatus == 'approved' || me.storyStatus == 'expired') {
					me.scheduleVO.publishBy = me.scheduleVO.oldPublishBy;
					me.scheduleVO.unPublishBy = me.scheduleVO.oldUnPublishBy;
				}
				me.storyStatus = me.oldStoryStatus;
				//alert(message);
				EP.Util.error.alert(message);
			}
			this.UI.updateState();
			if(data.storyResult.storyStatus == 'Purge') {
				window.location.href = this.dashboardUrl;
			}
		}

		$('html').toggleClass('has-pub-schedule', $('#publish_schedule:visible').length > 0);
		$('html').toggleClass('has-unpub-schedule', $('#unpublish_schedule:visible').length > 0);
	};

	proto.storyProxySave = function() {
		var me = this;
		if (isWorkflowTurnedOn)
		{
			$.post( me.formAction, {
				StoryMaster_storyProxyHeadline: me.storyHeadline,
				StoryMaster_storyLayoutId: me.layoutId,
				StoryMaster_siteId: me.siteId,
				StoryMaster_publishBy: me.publishBy,
				StoryMaster_unpublishBy: me.unpublishBy,
				StoryMaster_storyId: me.articleId,
				StoryMaster_storyAction: me.storyAction
			});
		}
	};

	proto.updateLock = function (me, nodes) {
		var lock = me.lock;
		//-- if locked by another user, lock w/ user icon
		if( lock && lock.locked ){
			nodes.btnLock.$.removeClass('lock unlock').addClass('by-user');
			jQuery('.portlet-content-container > .portlet-body').each( function(){
				EP.Util.disableOverlay( this );
			});
			EP.Util.disableOverlay( jQuery('.storyallmaster-portlet .portlet-content-container .portlet-body').get(0), false);
			EP.Util.disableToggle( $('#btn_save'), true );
			EP.Util.disableToggle( $('#btn_publish'), true );
			EP.Util.disableToggle( $('#btn_expire'), true );
			jQuery('#statusEdit').toggle(false);
		} else if(lock && lock.lockId) {
			nodes.btnLock.$.removeClass('unlock by-user').addClass('lock');
			jQuery('.portlet-content-container > .portlet-body').each( function(){
				EP.Util.disableOverlay( this, false );
			});
			EP.Util.disableToggle( $('#btn_save'), false );
			EP.Util.disableToggle( $('#btn_publish'), false );
			EP.Util.disableToggle( $('#btn_expire'), false );
			jQuery('#statusEdit').toggle(true);
		} else {
			if(me.storyStatus != "new") {
				nodes.btnLock.$.removeClass('lock by-user').addClass('unlock');
				jQuery('.portlet-content-container > .portlet-body').each( function(){
					EP.Util.disableOverlay( this );
				});
				EP.Util.disableOverlay( jQuery('.storyallmaster-portlet .portlet-content-container .portlet-body').get(0), false);
				if (!me.sharedByReference) {
					EP.Util.disableToggle( $('#btn_save'), true );
				} else {
					EP.Util.disableToggle( $('#btn_save'), false );
					EP.Util.disableOverlay( jQuery('.category-portlet .portlet-content-container .portlet-body').get(0), false);
					EP.Util.disableOverlay( jQuery('.topics-portlet .portlet-content-container .portlet-body').get(0), false);
				}
				EP.Util.disableToggle( $('#btn_publish'), true );
				EP.Util.disableToggle( $('#btn_expire'), true );
				jQuery('#statusEdit').toggle(false);
			}
		}
		if(lock && lock.lockedBy) {
			nodes.userLockStatus.$.html('Locked by ' + lock.lockedBy + ' at ' + lock.lockedTimeFormatted);
		} else {
			nodes.userLockStatus.$.html('Unlocked');
		}
	};
	
	proto.checkLock = function ( me ) {
		var url = '/story-wizard-portlet/restful/checkLock?articleId='+me.articleId+'&userId='+userId+'&groupId='+groupId;
		EP.io.request(url, {
			data : {
				val : {
					contentType : 'CREATESTORY',
					subType : 'checkLock'
				}
			},
			dataType : 'json',
			method : 'GET',
			sync: true,
			on : {
				success : function() {
					var obj = this.get('responseData');
					me.lock = obj.lock;
				}
			}
		});
	};

	proto.acquireLock = function(me, _nodes) {
		if (me.sharedByReference || me.storyStatus == "new" || me.articleId == "0") {
			return false;
		} else {
			var $btnLock = $(_nodes.btnLock.$);
			var oldLock = me.lock;
			var msgChange = '';
			me.checkLock( me );
			if( (me.lock.locked != oldLock.locked) || (me.lock.lockId != oldLock.lockId) || (me.lock.lockBy != oldLock.lockBy) ) {
				msgChange = '<strong>The page lock has been changed by others.</strong><br/><br/>';
				me.updateLock(me, me.UI.nodes);
			}
			if( $btnLock.hasClass('unlock') || $btnLock.hasClass('by-user') ) {
				me.UI.pageLockingModal.ask({
					msg : $btnLock.hasClass('by-user') ? msgChange+'This Page was ' + _nodes.userLockStatus.$.html() + '.<br/> Do you want to acquire a lock for 	this story page?' : msgChange+'Do you want to acquire a lock for this story page?',
					box : {
						text : 'Keep my changes'
					},
					cancel : {
						text : 'Cancel'
					},
					proceed : {
						text : 'Acquire Lock',
						action : function(checkFlag){
							//direct acquire lock and ignore others modification.
							var url = '/story-wizard-portlet/restful/acquireLock?articleId='+me.articleId+'&asAdmin='+$btnLock.hasClass('by-user')+'&userId='+userId+'&groupId='+groupId;
							EP.io.request(url, {
								data : {
									val : {
										contentType : 'CREATESTORY',
										subType : 'acquireLock'
									}
								},
								dataType : 'json',
								method : 'GET',
								on : {
									success : function() {
										var obj = this.get('responseData');
										me.lock = obj.lock;
										me.updateLock(me, _nodes);
										if(obj.success) {
											EP.Util.success.alert(obj.message||"Lock acquired.");
											if(!checkFlag) {
												//check box not checked, means reload page to fetch updated content
												window.location.reload();
											}
										} else {
											EP.Util.error.alert(obj.message||"Error acquiring lock.");
										}
									}
								}
							});
						}
					},
				});
				return true;
			} else {
				return false;
			}
		}
	};
	
	proto.writeDistributionsToPage = function(distributionStatus) {
		for (var idx in distributionStatus) {
			var station = distributionStatus[idx];
			// Disable the checkbox
			var el1 = jQuery('li[name=' + station.stationName + ']');
			el1.find(".channel").css("color", "#a5a5a5");
			el1.find(":checkbox")
					.prop("disabled", true)
					.prop("checked", true);
			
			// Update the status
			var status =  station.status;
			if (station.status == 'Published')
				status += ' (v' + station.version + ')';
			var button = '';
			if ((station.status != 'Published') && (station.status != 'Accepted'))
				button = '<button><span>x</span></button>';
			var el2 = jQuery('tr[name=' + station.stationName + ']');
			if (el2) {
				el2.find(".action").html("<b>" + status + "</b>" + button);
			}
		}
	};


})( jQuery );
liferay-plugin-package.properties
name=Story Wizard
module-group-id=endplay
module-incremental-version=1
tags=
short-description=
change-log=
page-url=http://www.endplay.com
author=EndPlay, Inc.
licenses=
required-deployment-contexts=ep-wcm-portlet,ep-data-media-portlet,article-distribution-portlet,feed-management-portlet,video-encode-portlet
portal-dependency-jars=\
	aopalliance.jar,\
	aspectj-rt.jar,\
    aspectj-weaver.jar,\
    cglib.jar,\
    commons-beanutils.jar,\
    commons-codec.jar,\
    commons-collections.jar,\
    commons-compress.jar,\
    commons-configuration.jar,\
    commons-dbcp.jar,\
    commons-digester.jar,\
    commons-discovery.jar,\
    commons-email.jar,\
    commons-fileupload.jar,\
    commons-httpclient.jar,\
    commons-io.jar,\
    commons-lang.jar,\
    commons-logging.jar,\
    commons-math.jar,\
    commons-pool.jar,\
    commons-validator.jar,\
    concurrent.jar,\
    hibernate3.jar,\
    jackson-all-1.8.0.jar,\
    jgroups.jar,\
    jstl-api.jar,\
    jstl-impl.jar,\
    spring-aop.jar,\
    spring-asm.jar,\
    spring-aspects.jar,\
    spring-beans.jar,\
    spring-context-support.jar,\
    spring-context.jar,\
    spring-core.jar,\
    spring-expression.jar,\
    spring-jdbc.jar,\
    spring-jms.jar,\
    spring-orm.jar,\
    spring-oxm.jar,\
    spring-transaction.jar,\
    spring-web-portlet.jar,\
    spring-web-servlet.jar,\
    spring-web-struts.jar,\
    spring-web.jar,\
    util-bridges.jar,\
    util-java.jar,\
    util-taglib.jar,\
    xstream.jar,\
    xpp3.jar
portal-dependency-tlds=\
    c.tld,\
    fn.tld
newJS
( function($){

	EP.Portlets.StoryMaster = function(config) {
		this.__init(config);
	};

	var proto = EP.Portlets.StoryMaster.prototype;

	proto.__init = function(config) {
		
		this.scheduleVO = {};
		
		this.storyAction;

		//-- if config available, set from config
		if(config) {
			this.storyHeadline = "";
			this.id = config.id;
			this.articleId = config.masterPageId;
			this.oldArticleId = config.oldPageId;
			this.type = config.pageType;
			this.oldType = config.oldPageType;
			this.pageTypeId = config.pageTypeId;
			this.storyLayoutId = 0;
			this.siteId = config.siteId;
			this.publishBy = config.publishDate;
			this.unpublishBy = config.unPublishDate;
			this.defaultTemplateCategoryId = config.defCategoryId;
			this.layoutId = config.layoutId;
			this.scheduleVO.publishBy = config.publishDate;
			this.scheduleVO.oldPublishBy = "None";
			this.scheduleVO.unPublishBy = config.unPublishDate;
			this.scheduleVO.oldUnPublishBy = "None";
			this.formAction = config.formAction;
			this.storyVersions = config.storyVersions;
			this.currentVersion = config.currentVersion;
			this.storyTransitionStates = config.storyTransitionStates;
			this.storyStatus = config.storyStatus;
			this.defaultArticleRequestId = config.defaultArticleRequestId;
			this.lock = config.lock;
			this.editable = config.editable;
			this.sharedByReference = config.sharedByReference;
			this.htmlPageTitle = config.htmlPageTitle;
			this.dashboardUrl = config.dashboardUrl;
			this.operation = config.operation;
			this.siteTimeZone = config.siteTimeZone;
			this.lockStoryMasterToTop = config.lockStoryMasterToTop;
			this.sourceId = config.sourceId;
			this.defaultPageFlag = config.defaultPageFlag;
			document.title = config.htmlPageTitle;
		}

		this.UI = {}; //-- UI object
	};
		
	proto.read = function() {
	};
		
	proto.write = function() {
		
	};

	proto.toJSON  = function () {
		var jsonObj = {};
		
		for( x in this ){
			if( x != 'UI' && x != 'expireScheduleEditor' && x != 'publishScheduleEditor'){
				jsonObj[x] = this[x];
			}
		}

		return jsonObj;
	};

	proto.render = function() {
		var me = this;

		//-- Lock Story Master for to top (fixed position)
		if( this.lockStoryMasterToTop ) {
			$('html').addClass('fixed-master');
		}

		//-- UI Nodes; default jQuery
		me.UI.nodes = {};
		var _nodes = me.UI.nodes;
		
		_nodes.storyMaster = { $ : jQuery('.storyallmaster-portlet') };
		_nodes.btnLock = { $ : _nodes.storyMaster.$.find('#btn-lock') };
		_nodes.portletSettings = { $ : _nodes.storyMaster.$.find('.portlet-settings') };
		_nodes.btnCopyStory = { $ : _nodes.storyMaster.$.find('.btn[name="copy-story"]') };
		_nodes.btnDeleteStory = { $ : _nodes.storyMaster.$.find('.btn[name="delete-story"]') };
		_nodes.userLockStatus = { $ : _nodes.storyMaster.$.find('.user-lock-status div') };
		_nodes.btnPreview = { $ : _nodes.portletSettings.$.find('.btn[name="preview"]') };

		//-- copy the active story to a new tab
		_nodes.btnCopyStory.$.bind('click', function(){
			window.open(window.location.pathname + '?type=' + me.pageTypeId + '&storyId='+ me.articleId + '&isCopy=true' + '&pageTitle=' + 'Copy of ' + me.htmlPageTitle, //-- copy story URL
				'Copy_of_Story_' + Math.floor( 1000 * Math.random() ) //-- window name
			);
		});
		
		this.updateLock(me, _nodes);
		
		_nodes.btnLock.$.bind('click', function(){
			var $this = $(this);
			var oldLock = me.lock;
			var msgChange = '';
			me.checkLock( me );
			if( (me.lock.locked != oldLock.locked) || (me.lock.lockId != oldLock.lockId) || (me.lock.lockBy != oldLock.lockBy) ) {
				msgChange = '<strong>The page lock has been changed by others.</strong><br/><br/>';
				me.updateLock(me, _nodes);
			}
			if($this.hasClass('unlock') || $this.hasClass('by-user')){
				me.UI.pageLockingModal.ask({
					msg : $this.hasClass('by-user') ? msgChange+'This Page was ' + _nodes.userLockStatus.$.html() + '.<br/> Do you want to acquire a lock for this story?' : msgChange+'Do you want to acquire a lock for this story?',
					box : {
						text : 'Keep my changes'
					},
					cancel : {
						text : 'Cancel'
					},
					proceed : {
						text : 'Acquire Lock',
						action : function(checkFlag){
							//direct acquire lock and ignore others modification.
							var url = '/story-wizard-portlet/restful/acquireLock?articleId='+me.articleId+'&asAdmin='+$this.hasClass('by-user')+'&userId='+userId+'&groupId='+groupId;
							EP.io.request(url, {
								data : {
									val : {
										contentType : 'CREATESTORY',
										subType : 'acquireLock'
									}
								},
								dataType : 'json',
								method : 'GET',
								on : {
									success : function() {
										var obj = this.get('responseData');	
										me.lock = obj.lock;
										me.updateLock(me, _nodes);
										if(obj.success) {
											EP.Util.success.alert(obj.message||"Lock acquired.");
											if(!checkFlag) {
												//check box not checked, means reload page to fetch updated content
												window.location.reload();
											}
										} else {
											EP.Util.error.alert(obj.message||"Error acquiring lock.");
										}
									}
								}
							});
						}
					},
				});
			} else {
				me.UI.pageLockingModal.ask({
					msg : msgChange+'Do you want to release the lock on this story?',
					cancel : {
						text : 'Cancel'
					},
					proceed : {
						text : 'Release Lock',
						action : function(){
							var url = '/story-wizard-portlet/restful/releaseLock?lockId='+me.lock.lockId+'&articleId='+me.articleId+'&userId='+userId+'&groupId='+groupId;
							EP.io.request(url, {
								data : {
									val : {
										contentType : 'CREATESTORY',
										subType : 'releaseLock'
									}
								},
								dataType : 'json',
								method : 'GET',
								on : {
									success : function() {
										var obj = this.get('responseData');	
										me.lock = obj.lock;
										me.updateLock(me, _nodes);
										if(obj.success) {
											EP.Util.success.alert(obj.message||"Lock released.");
										} else {
											EP.Util.error.alert(obj.message||"Error releasing lock.");
										}
									}
								}
							});
						}
					},
				});
			}
			$this.blur();
		}).hover( function(){
			if( _nodes.userLockStatus.$.queue('fx').length < 1 ){
				_nodes.userLockStatus.$.effect( 'slide', {
					direction : 'left',
					mode : 'show'
				}, 500 );
			} else {
				_nodes.userLockStatus.$.dequeue('fx').removeAttr('style');

			}
		}, function(){
			if( _nodes.userLockStatus.$.queue('fx').length < 1 ){
				_nodes.userLockStatus.$.effect( 'slide', {
					direction : 'left',
					mode : 'hide'
				}, 500 );
			} else {
				_nodes.userLockStatus.$.dequeue('fx').removeAttr('style');
			}
		});

		window.onbeforeunload = function(){
			// Story.js will call onbeforeunload first
			if (me.storyStatus != 'new') {
				var $this = _nodes.btnLock.$;
				me.checkLock( me );
				me.updateLock(me, _nodes);
				if(!$this.hasClass('unlock') && !$this.hasClass('by-user')) {
					var url = '/story-wizard-portlet/restful/releaseLock?lockId='+me.lock.lockId+'&articleId='+me.articleId+'&userId='+userId+'&groupId='+groupId;
					EP.io.request(url, {
						data : {
							val : {
								contentType : 'CREATESTORY',
								subType : 'releaseLock'
							}
						},
						dataType : 'json',
						method : 'GET',
						sync: true,
						on : {success : function() {}}
					});
				}
				return;
			}
		};
		
		_nodes.btnPreview.$.live('click', function(){
			var $this = _nodes.btnPreview.$;
			
			if( !$this.attr('disabled') ){
				
				var checkedDefaultFlag = document.getElementById('page-default').checked;
				if( !me.defaultPageFlag && (checkedDefaultFlag == true) ) {
					// TPRA-2434   //sync save
					__WS_StoryMaster.save( true );
				}
				window.open( $this.attr('value'), "PREVIEW");
			}
		});

		//-- UI setup
		me.UI.updateState = function(){
			//-- articleId means published
			if( me.articleId ){
				//_nodes.btnPreview.$.show();
				//_nodes.btnCopyStory.$.show();
				//_nodes.btnDeleteStory.$.show();
				EP.Util.disableToggle( _nodes.btnPreview.$, false );
				EP.Util.disableToggle( _nodes.btnCopyStory.$, false );
				EP.Util.disableToggle( _nodes.btnDeleteStory.$, false );
				_nodes.storyMaster.$.addClass('lockable');
			} else {
				//_nodes.btnPreview.$.hide();
				//_nodes.btnCopyStory.$.hide();
				//_nodes.btnDeleteStory.$.hide();
				EP.Util.disableToggle( _nodes.btnPreview.$, true );
				EP.Util.disableToggle( _nodes.btnCopyStory.$, true );
				EP.Util.disableToggle( _nodes.btnDeleteStory.$, true );
				_nodes.storyMaster.$.removeClass('lockable');
			}
		};
		
		//-- manage expansion of settings hanging tab
		me.UI.updateOverlayPush = function(){
			jQuery('#column-3').css(
				'padding-top',
				_nodes.portletSettings.$.height()
			);
		};

		//-- format incoming version values before adding to UI
		me.formatVersionText = function( value ){

			var splitStr = value.split(' - ');

			var newValue = '<span class="version">'
				+ splitStr[0].substring(8)
				+ '</span><span class="timestamp">'
				+ splitStr[1]
				+ '</span><span class="author">'
				+ splitStr[2] + '</span>';

			return newValue;
		};
		
		//-- get version from value
		me.getVersion = function( value ){

			var splitStr = value.split(' - ');
			var version = splitStr[0].substring(8);

			return version;
		};

		jQuery('div#storyVersion').show();
		if (me.storyVersions && me.storyVersions.length > 0) {
			jQuery.each(me.storyVersions, function(index, value){
				jQuery('#story-version-list').append('<li value="' + me.getVersion( value) + '">' + me.formatVersionText( value ) + '</li>');
			});
			$('#selectedStoryVersion').html( me.currentVersion );
			$('#story-version-list').find('li[value="' + me.currentVersion + '"]').addClass('active');
		} else {
			jQuery('#story-version-list').append('<li value="-1"><span class="version">No saved versions</span></li>');
			$('#story-version-list').find('li[value="-1"]').addClass('active');
		}
		
		if (me.storyTransitionStates) {
			jQuery.each(me.storyTransitionStates, function(key, value){
				jQuery('#storyStatesList').append( '<li id="' + value.transitionValue + '">' + value.transitionLabel +  '</li>' );
			});
		}
		
		/**** EVENTS ****/
		
		//-- show available versions
		$('.btn[name="show-version-list"]').bind('click', function(e){
			$(this).blur();
			$('#story-version-list').addClass('active');
			$('body').bind('click', function(e){
				if( $( e.target ).get(0) != $('#story-version-list').get(0) ){
					$('#story-version-list').removeClass('active');
					$(this).unbind('click');
				}
			});
			e.stopPropagation();
		});

		//-- on list click, select appropriate version
		$('#story-version-list').find('li').live('click', function(i){
			var $this = $(this);
			var value = this.getAttribute('value');
//			var optionVer = $('#storyVersions').find('option');
//			var selectedVer = optionVer.filter('option:selected');
			if( $('#story-version-list li').length > 1 ){
				me.UI.confirmationModal.ask({
					msg : 'Changing a story version will delete any unsaved edits',
					cancel : {
						text : 'Cancel'
					},
					proceed : {
						text : 'Change Version',
						action : function(){
							$this.siblings('li').removeClass('active').end();
							 AUI().use(
								'ep-io-request',
								function(A) {
									var url = '/story-wizard-portlet/restful/storyversionget?storyId='+me.articleId+'&storyVersionNumber='+value+'&type='+me.pageTypeId+'&userId='+userId+'&groupId='+groupId;
									EP.io.request(url, {
										dataType : 'json',
										
										data : {
											val : {
												contentType : 'CREATESTORY',
												subType : 'CHANGE_VERSION',
												groupId : groupId,
												type : me.pageTypeId,
												storyId : me.articleId,
												storyVersionNumber : value,
												userId : userId
											}	
										},
										
										
										method : 'GET',
										on : {
											success : function() {
												var obj = this.get('responseData');	
												obj.storyVO.settingsVO = {};
												obj.storyVO.settingsVO.version = value;
												__WS_StoryMaster.refreshVersionData({storyAbstract : obj.storyVO.storyAbstract,
													 storyBody : obj.storyVO.storyBody,
													 version : value,
													 updateVersionedFieldsData : true});
												me.currentVersion = value;
												
												$('#story-version-list').find('li[value="' + value + '"]').addClass('active');
												$('#selectedStoryVersion').html( value );
											}
										}
									});
								});
							$('#storyVersions').val( value ).trigger('change');
							$('#story-version-list').removeClass('active');
						}
					},
				});
			}
		});

		//-- show page status options; hide on click outside container
		jQuery('#statusEdit').click( function(e) {
			$(this).blur();
			jQuery('#storyStatesList').show();
			$('body').bind('click', function(e){
				if( $( e.target ).get(0) != $('#storyStatesList').get(0) ){
					jQuery('#storyStatesList').hide();
					$(this).unbind('click');
				}
			});
			e.stopPropagation();
		});
		
		if (me.sharedByReference) {
			$('#update-btn').show();
//			$('span#unpublish_schedule').disable();
//			$('#storyVersion')
		} 
		if (me.storyStatus == 'new') {
			$('#save-btn').show();
			$('#publish-btn').show();
			$('span#unpublish_schedule').hide();
		} else if (me.storyStatus == 'draft') {
			$('#save-btn').show();
			$('#publish-btn').show();
			$('span#unpublish_schedule').hide();
		} else {
			$('span#unpublish_schedule').toggle(true);
			$('#save-btn').show();
			if (me.storyStatus == 'approved') {
				$('#publish-btn').hide();
				if(me.scheduleVO.unPublishBy == 'None') {
					$('#expire-btn').show();
				} else {
					$('#expire-btn').hide();
				}
				$('#publish_schedule').hide();
				$('#unpublish_schedule').show();
			} else if (me.storyStatus == 'expired')	{
				if(me.scheduleVO.publishBy == 'None') {
					$('#publish-btn').show();
				} else {
					$('#publish-btn').hide();
				}
				$('#expire-btn').hide();
				$('#publish_schedule').show();
				$('#unpublish_schedule').hide();
			} else if (me.storyStatus == 'Deleted')	{
				$('#publish-btn').hide();
				$('#expire-btn').hide();
				$('#publish_schedule').hide();
				$('#unpublish_schedule').hide();
			} else {
				$('#publish-btn').show();
				$('#expire-btn').hide();
				$('#publish_schedule').show();
				$('#unpublish_schedule').show();
			}		
			jQuery('#statusEdit').toggle(true);
		}
		
		$('html').toggleClass('has-pub-schedule', $('#publish_schedule:visible').length > 0);
		$('html').toggleClass('has-unpub-schedule', $('#unpublish_schedule:visible').length > 0);

		$('#storyStatesList li').live('click', function(){
			if(!me.acquireLock(me,_nodes)) {
				var $this = $(this);			
				var afterConfirm = function(){
					var currentStatus = me.storyStatus;
					me.oldStoryStatus = currentStatus;
					me.storyStatus = $this.attr('id');
					if (me.storyStatus == 'approved') {
						me.storyAction = 'Publish';
						me.scheduleVO.publishBy = 'Immediately';
						me.scheduleVO.unPublishBy = 'None';
					} else if (me.storyStatus == 'expired')	{
						me.storyAction = 'UnPublish';
						me.scheduleVO.publishBy = 'None';
						me.scheduleVO.unPublishBy = 'Immediately';
					} else {
						me.storyAction = '';
						me.scheduleVO.publishBy = 'None';
						me.scheduleVO.unPublishBy = 'None';
					}
				    me.stateChangeRequest = true;
					jQuery('#storyStatesList').toggle(false);
					me.checkLock( me );
					me.updateLock(me, _nodes);
					__WS_StoryMaster.save();
					me.stateChangeRequest = false;
				};
				var changeStatus = $this.attr('id');
				if(changeStatus == 'Purge')
				{
				    var cancel_btn = me.UI.confirmPurgeModal.get().bodyNode.one('.btn[name="cancel"]');
					cancel_btn.setStyle('marginLeft', '410px');
				    me.UI.confirmPurgeModal.ask({
						msg :'<b>Permanently Remove?</b><br/> Once you Purge content, it cannot be restored.',
						cancel : {
							text : 'Cancel'
						},
						proceed : {
							text : 'Purge',
							action : function(){
								 afterConfirm();
							}
						},
					});	
				
				} else {
				  afterConfirm();
				}
			}
		});
		//-- render
		me.UI.updateState();
		
		$('#btn_publish').click(function() {
			if(!me.acquireLock(me,_nodes)) {
				var currentStatus = me.storyStatus;
				me.oldStoryStatus = currentStatus;
				me.storyStatus = 'approved';
				me.storyAction = 'Publish';
				me.scheduleVO.oldPublishBy = me.scheduleVO.publishBy;
				me.scheduleVO.oldUnPublishBy = me.scheduleVO.unPublishBy;
				me.scheduleVO.publishBy = 'Immediately';
				me.scheduleVO.unPublishBy = me.scheduleVO.oldUnPublishBy;
				var successful = EP.Controllers[masterAttrName].save();
				if(!successful) {
					// if front end validate failed, roll back here.
					me.storyStatus = me.oldStoryStatus;
					me.scheduleVO.publishBy = me.scheduleVO.oldPublishBy;
					me.scheduleVO.unPublishBy = me.scheduleVO.oldUnPublishBy;
				}
			}
		});
		
		$('#btn_save').click(function() {
			if(!me.acquireLock(me,_nodes)) {
				var currentStatus = me.storyStatus;
				me.oldStoryStatus = currentStatus;
				me.storyStatus = 'draft';
				me.storyAction = 'Saved';
				var successful = EP.Controllers[masterAttrName].save();
				if(!successful) {
					// if front end validate failed, roll back here.
					me.storyStatus = me.oldStoryStatus;
				}
			}
		});
		
		$('#btn_expire').click(function() {
			if(!me.acquireLock(me,_nodes)) {
				var currentStatus = me.storyStatus;
				me.oldStoryStatus = currentStatus;
				me.storyStatus = 'expired';
				me.storyAction = 'UnPublish';
				me.scheduleVO.oldPublishBy = me.scheduleVO.publishBy;
				me.scheduleVO.oldUnPublishBy = me.scheduleVO.unPublishBy;
				me.scheduleVO.publishBy = 'None';
				me.scheduleVO.unPublishBy = 'Immediately';
				var successful = EP.Controllers[masterAttrName].save();
				if(!successful) {
					// if front end validate failed, roll back here.
					me.storyStatus = me.oldStoryStatus;
					me.scheduleVO.publishBy = me.scheduleVO.oldPublishBy;
					me.scheduleVO.unPublishBy = me.scheduleVO.oldUnPublishBy;
				}
			}
		});
				
		$('#btn_update').click(function() {
			if(!me.acquireLock(me,_nodes)) {
				var currentStatus = me.storyStatus;
				me.oldStoryStatus = currentStatus;
				me.storyAction = 'Update';
				var successful = EP.Controllers[masterAttrName].save();
				if(!successful) {
					// if front end validate failed, roll back here.
					me.storyStatus = me.oldStoryStatus;
				}
			}
		});
		
		var storyMasterSchedule = null;
		var storyMasterUnpublishSchedule = null;

		//-- AUI
		AUI().use('ep-dialog-confirmation', function(A){

			me.UI.confirmationModal = new EP.Components.confirmationDialog({
				dialog : {
					dialogOptions : {
						title : 'Version Change'
					}
				}
			});

			me.UI.rejectShareModal = new EP.Components.confirmationDialog({
				dialog : {
					dialogOptions : {
						title : 'Reject Share'
					}
				}
			});
			
			me.UI.releaseLockModal = new EP.Components.confirmationDialog({
				dialog : {
					dialogOptions : {
						title : 'Release Lock'
					}
				}
			});
			
			me.UI.pageLockingModal = new EP.Components.confirmationDialog({
				dialog : {
					dialogOptions : {
						title : 'Page Locking'
					}
				}
			});
			
			me.UI.confirmPurgeModal = new EP.Components.confirmationDialog({
				dialog : {
					dialogOptions : {
						title : 'Purge content'
					}
				}
			});
		});
		
		$(document).ready(function(){
			me.publishScheduleEditor = $('StoryMaster_schedule').scheduleEditor({
				defaultValue: me.scheduleVO.publishBy,
				hasImmediately: false,
				hasNone: true,
				siteTimeZone: me.siteTimeZone,
				hasNone: true,
				selector:'StoryMaster_schedule',
				onFinishEdit: function(value) {
					if(value['schedule'] == 'None') {
						me.scheduleVO.publishBy = 'None';
					} else if(value['schedule'] == 'Immediately') {
						me.scheduleVO.publishBy = 'Immediately';
					} else {
						me.scheduleVO.publishBy = value['scheduleMonth']
							+'/'+ value['scheduleDay']
							+'/'+ value['scheduleYear']
							+' '+ value['scheduleHour']
							+':'+ value['scheduleMinute']
							+' '+ value['ampm']
							+' '+ value['timezone'];
							$('#publish-btn').hide();
					}
					
					if (me.storyStatus == 'new') {
						$('#expire-btn').hide();
						if(me.scheduleVO.publishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					} else if (me.storyStatus == 'draft') {
						$('#expire-btn').hide();
						if(me.scheduleVO.publishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					} else if (me.storyStatus == 'approved') {
						$('#publish-btn').hide();
						if(me.scheduleVO.unPublishBy == 'None') {
							$('#expire-btn').show();
						} else {
							$('#expire-btn').hide();
						}
					} else if (me.storyStatus == 'expired') {
						$('#expire-btn').hide();
						if (me.scheduleVO.publishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					} else {
						$('#expire-btn').hide();
						if (me.scheduleVO.publishBy == 'None' 
							&& me.scheduleVO.unPublishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					}
					
				},
				onSaveCheck: function(value, date) {
					var result = value;
					if (storyMasterUnpublishSchedule != null &&
						date < storyMasterUnpublishSchedule) {
					result += "the publish date is before the unpublish date\n";
					} else {
						storyMasterSchedule = date;
					}
					return result;
				}
			});
				
			me.expireScheduleEditor  = $('StoryMaster_unpublish_schedule').scheduleEditor({
				defaultValue: me.scheduleVO.unPublishBy,
				hasImmediately: false,
				hasNone: true,
				siteTimeZone: me.siteTimeZone,
				selector: 'StoryMaster_unpublish_schedule',
				disabled: me.sharedByReference,
				onFinishEdit: function(value){
					if(value['schedule'] == 'None') {
						me.scheduleVO.unPublishBy = 'None';
					} else if(value['schedule'] == 'Immediately') {
						me.scheduleVO.unPublishBy = 'Immediately';
					} else {
						me.scheduleVO.unPublishBy = value['scheduleMonth']
							+'/'+ value['scheduleDay']
							+'/'+ value['scheduleYear']
							+' '+ value['scheduleHour']
							+':'+ value['scheduleMinute']
							+' '+ value['ampm']
							+' '+ value['timezone'];
					}
					
					if (me.storyStatus == 'new') {
						$('#expire-btn').hide();
						if(me.scheduleVO.publishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					} else if (me.storyStatus == 'draft') {
						$('#expire-btn').hide();
						if(me.scheduleVO.publishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					} else if (me.storyStatus == 'approved') {
						$('#publish-btn').hide();
						if(me.scheduleVO.unPublishBy == 'None') {
							$('#expire-btn').show();
						} else {
							$('#expire-btn').hide();
						}
					} else if (me.storyStatus == 'expired') {
						$('#expire-btn').hide();
						if (me.scheduleVO.publishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					} else {
						$('#expire-btn').hide();
						if (me.scheduleVO.publishBy == 'None' 
							&& me.scheduleVO.unPublishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
					}
					
				},
				onSaveCheck: function(value, date) {
					var result = value;
					if (storyMasterSchedule != null &&
						date < storyMasterSchedule) {
						result += "the publish date is before the unpublish date\n";
					} else {
						storyMasterUnpublishSchedule = date;
					}
					return result;
				},
				changeExpirationDate:function(date){
					var tmp = date;
					this.contents_new['schedule'] = 'Scheduled';
					this.contents_new['scheduleMonth'] = tmp.substring(0, tmp.indexOf("/"));
					tmp = tmp.substring(tmp.indexOf("/") + 1);
					this.contents_new['scheduleDay'] = tmp.substring(0, tmp.indexOf("/"));
					tmp = tmp.substring(tmp.indexOf("/") + 1);
					this.contents_new['scheduleYear'] = tmp.substring(0, tmp.indexOf(" "));
					tmp = tmp.substring(tmp.indexOf(" ") + 1);
					this.contents_new['scheduleHour'] = tmp.substring(0, tmp.indexOf(":"));
					tmp = tmp.substring(tmp.indexOf(":") + 1);
					this.contents_new['scheduleMinute'] = tmp.substring(0, tmp.indexOf(" "));
					tmp = tmp.substring(tmp.indexOf(" ") + 1);
					this.contents_new['ampm'] = tmp.substring(0, tmp.indexOf(" "));
					tmp = tmp.substring(tmp.indexOf(" ") + 1);
					this.contents_new['timezone'] = tmp;
				}
			});
		});
		
		$(document).ready(function(){
			if (!me.editable) {
				jQuery('.portlet-content-container > .portlet-body').each( function(){
					EP.Util.disableOverlay( this );
				});
				EP.Util.disableOverlay( jQuery('.storyallmaster-portlet .portlet-content-container .portlet-body').get(0), false);
			} else {
				// overlay content to the locked page by others or unlocked, until acquire lock from others
				if(me.lock && me.lock.locked) {
					jQuery('.portlet-content-container > .portlet-body').each( function(){
						EP.Util.disableOverlay( this );
				    });
					EP.Util.disableOverlay( jQuery('.storyallmaster-portlet .portlet-content-container .portlet-body').get(0), false);
					EP.Util.disableToggle( $('#btn_save'), true );
					EP.Util.disableToggle( $('#btn_publish'), true );
					EP.Util.disableToggle( $('#btn_expire'), true );
					jQuery('#statusEdit').toggle(false);
				} else if(me.lock && me.lock.lockId) {
					jQuery('.portlet-content-container > .portlet-body').each( function(){
						EP.Util.disableOverlay( this, false );
					});
					EP.Util.disableToggle( $('#btn_save'), false );
					EP.Util.disableToggle( $('#btn_publish'), false );
					EP.Util.disableToggle( $('#btn_expire'), false );
					jQuery('#statusEdit').toggle(true);
				} else {
					if(me.storyStatus != 'new') {
						jQuery('.portlet-content-container > .portlet-body').each( function(){
							EP.Util.disableOverlay( this );
					    });
						EP.Util.disableOverlay( jQuery('.storyallmaster-portlet .portlet-content-container .portlet-body').get(0), false);
						EP.Util.disableToggle( $('#btn_save'), true );
						EP.Util.disableToggle( $('#btn_publish'), true );
						EP.Util.disableToggle( $('#btn_expire'), true );
						jQuery('#statusEdit').toggle(false);
					}
				}
			}
			if (me.sharedByReference) {
				jQuery('#wrapper').addClass('isShared');
				EP.Util.disableOverlay( jQuery('.category-portlet .portlet-content-container .portlet-body').get(0), false);
				EP.Util.disableOverlay( jQuery('.topics-portlet .portlet-content-container .portlet-body').get(0), false);
				jQuery('#statusEdit').hide();
				
//				$('#unpublish_schedule').hide();
//				$('#publish_schedule').hide();
				$('#publish-btn').hide();
				$('#expire-btn').hide();
				$('#save-btn').hide();
				$('#update-btn').show();
				$('#statusEdit').hide();
				
			}
		});
		
		$('#reject-story').click(function(){
			me.UI.rejectShareModal.ask({
				msg : 'Are you sure you want to reject? Once Rejected, page(s) cannot be restored.',
				cancel : {
					text : 'Cancel'
				},
				proceed : {
					text : 'Okay',
					action : function(){
						var url = '/story-wizard-portlet/restful/rejectShare?storyId='+me.articleId+'&userId='+userId+'&groupId='+groupId;
						EP.io.request(url, {
							data : {
								val : {
									contentType : 'CREATESTORY',
									subType : 'rejectShare'
								}
							},
							dataType : 'json',
							method : 'GET',
							on : {
								success : function() {
									var obj = this.get('responseData');	
									if(obj.success) {
										window.close();
									} else {
										EP.Util.error.alert(obj.message||"Error Rejecting Shared Page");
									}
								}
							}
						});
					}
				},
			});
		});
				
		_nodes.btnDeleteStory.$.bind('click', function(){
			me.UI.rejectShareModal.ask({
				msg : '<b>Permanently Remove?</b><br/> Once you Delete content, it cannot be restored.',
				cancel : {
					text : 'Cancel'
				},
				proceed : {
					text : 'Okay',
					action : function(){
						var url = '/story-wizard-portlet/restful/deleteStory?articleId='+me.articleId+'&userId='+userId+'&groupId='+groupId;
						EP.io.request(url, {
							data : {
								val : {	}
							},
							dataType : 'json',
							method : 'GET',
							on : {
								success : function() {
									var obj = this.get('responseData');	
									if(obj.success) {
										window.close();
									} else {
										EP.Util.error.alert(obj.message||"Error Deleting Story.");
									}
								}
							}
						});
					}
				}
			});
		});
	};	
	
	proto.preSave = function(data) {
		this.storyHeadline = data.storyVO.headline;
		if(data.storyVO.settingsVO.selectedContentType){
			this.type = data.storyVO.settingsVO.selectedContentType;
		}
		if(data.storyVO.settingsVO.contentType) {
			if(data.storyVO.settingsVO.contentType == "Gallery") {
				this.type = "gallery";
			}else if(data.storyVO.settingsVO.contentType == "ListGallery") {
				this.type = "list-gallery";
			}
		}
		
		return data;
	};
		
	proto.postSave = function(data) {
		var me = this;
		var message = '';
		var internalUrl = '';
		if(data.storyResult && data.storyResult.success != null) {
			if(data.storyResult.success == true) {
				if(data.storyResult.articleId) {
					//message = data.storyResult.response;
					switch(data.storyResult.storyStatus){
						case 'approved' :
							if ( me.sharedByReference )
								statusDisplayMessage = 'Has been <span style="background-color: #349405; color: #FFFFFF; font-weight: bold; padding: 3px 6px;">Updated</span>';
							else
								statusDisplayMessage = 'Has been <span style="background-color: #349405; color: #FFFFFF; font-weight: bold; padding: 3px 6px;">Published</span>';
							break;
						case 'draft' :
							statusDisplayMessage = 'Has been saved as a <span style="background-color: #3F3E3D; color: #FFFFFF; font-weight: bold; padding: 3px 6px;">Draft</span>';
							break;
						case 'expired' :
							statusDisplayMessage = 'Has been <span style="background-color: #8B8B8B; color: #FFFFFF; font-weight: bold; padding: 3px 6px;">Expired</span>';
							break;
						default :
							statusDisplayMessage = 'Has been saved as a <span style="background-color: #3F3E3D; color: #FFFFFF; font-weight: bold; padding: 3px 6px;">'+data.storyResult.storyStatus+'</span>';
					}
					
					message = message
						+ '<div style="margin-bottom: 10px;"><span style="font-weight: bold; font-size: 14px;">Story Headline : </span>' + data.storyResult.headline + '</div>'
						+ '<div style="margin-bottom: 10px;"><span style="font-weight: bold; font-size: 14px;">Story Page ID : </span>' + data.storyResult.articleId + '</div>'
						+ '<div style="margin-bottom: 10px;">' + statusDisplayMessage + '</div>';
				}
				
				if ( me.sharedByReference ) {
					EP.Util.success.alert(message);
					return;
				}
				
				// reset default article request flag
				this.defaultArticleRequestId = null;
				
				if(data.storyResult.unpublishBy) {
					$('#StoryMaster_unpublish_schedule').text(data.storyResult.unpublishBy);
					this.expireScheduleEditor.changeExpirationDate.call(this.expireScheduleEditor,data.storyResult.unpublishBy);
				}
				
				if(data.storyResult.defaultPageFlag) {
					this.defaultPageFlag = data.storyResult.defaultPageFlag;
				}
				
				if (this.storyVO.settingsVO.sourceId != null) {
					this.sourceId = this.storyVO.settingsVO.sourceId;
				}
				else if(data.storyResult.sourceId) {
					this.sourceId = data.storyResult.sourceId;
				}
				
				if(data.storyResult.url) {
					internalUrl = data.storyResult.url;
					jQuery('#storyall-master_url').html(internalUrl);
				}
				
				//if(data.storyResult.layoutPath) {
				//	jQuery('button[name="preview"]').attr('value',data.storyResult.layoutPath);
				//}
				
				if(data.storyResult.articleId) {
					jQuery('button[name="preview"]').attr('value', viewNonstoryUrl + data.storyResult.urlTitle  + '?workflowAssetPreview=true&version=' + data.storyResult.currentVersion);
				}
				
				if (data.storyResult.storyVersions)	{
					jQuery('div#storyVersion').show();
					jQuery('#story-version-list').find('li').remove().end();
					jQuery.each(data.storyResult.storyVersions, function(index, value){
						jQuery('#story-version-list').append('<li value="' + me.getVersion( value) + '">' + me.formatVersionText( value ) + '</li>');
					});
					$('#selectedStoryVersion').html(data.storyResult.currentVersion );
					$('#story-version-list').find('li[value="' +data.storyResult.currentVersion + '"]').addClass('active');
				}
				
				if (data.storyResult.articleId) {
					this.articleId = data.storyResult.articleId;
					jQuery('#story_page_id').html(this.articleId);
				}
				
				if(data.storyResult.layoutId) {
					this.storyLayoutId = data.storyResult.layoutId;
				}
				
				if(data.storyResult.siteId) {
					this.siteId = data.storyResult.siteId;
				}
				
				if(data.storyResult.publishBy) {
					this.publishBy = data.storyResult.publishBy;
					this.scheduleVO.publishBy = data.storyResult.publishBy;
				}
							
				if(data.storyResult.unpublishBy) {
					this.unpublishBy = data.storyResult.unpublishBy;
					this.scheduleVO.unPublishBy = data.storyResult.unpublishBy;
				}
				
				if(data.storyResult.storyAction) {
					this.storyAction = data.storyResult.storyAction;
				}
				
				if(data.storyResult.lockVO) {
					this.lock = data.storyResult.lockVO;
					this.updateLock(this, this.UI.nodes);
				}
				if(data.storyResult.description) {
					$('#description').val(data.storyResult.description);
				}
				if(data.storyResult.shortHeadline) {
					$('#input_short-headline').val(data.storyResult.shortHeadline);
				}
				if(data.storyResult.urlTitle) {
					$('#file-name').val(data.storyResult.urlTitle);
				}
				if(data.storyResult.title) {
					$('#page-name').val(data.storyResult.title);
				}
				if(data.storyResult.title) {
					$('#page-title').val(data.storyResult.title);
				}
				this.storyProxySave();
				if (data.storyResult.storyStatus) {
					// handle status display
					var statusDisplay = data.storyResult.storyStatus;
					if (data.storyResult.storyStatus == 'approved') {
						statusDisplay = 'published';
					} else if (data.storyResult.storyStatus == 'expired') {
						statusDisplay = 'expired';
					}
					
					$('#storyStatusLabel').text( statusDisplay.toUpperCase());
					$('#save-btn').show();
					$('span#unpublish_schedule').toggle(true);
					me.storyStatus = data.storyResult.storyStatus;
					if (me.storyStatus == 'approved') {
						$('#publish-btn').hide();
						if(me.scheduleVO.unPublishBy == 'None') {
							$('#expire-btn').show();
						} else {
							$('#expire-btn').hide();
						}
						$('#publish_schedule').hide();
						$('#unpublish_schedule').show();
					} else if (me.storyStatus == 'expired')	{
						if(me.scheduleVO.publishBy == 'None') {
							$('#publish-btn').show();
						} else {
							$('#publish-btn').hide();
						}
						$('#expire-btn').hide();
						$('#publish_schedule').show();
						$('#unpublish_schedule').hide();
					} else if (me.storyStatus == 'Deleted')	{
						$('#publish-btn').hide();
						$('#expire-btn').hide();
						$('#publish_schedule').hide();
						$('#unpublish_schedule').hide();
					} else {
						$('#publish-btn').show();
						$('#expire-btn').hide();
						$('#publish_schedule').show();
						$('#unpublish_schedule').show();
					}
					
					jQuery('#statusEdit').toggle(true);

					if ((me.oldStoryStatus == 'new' || me.pageTypeId != data.storyResult.type)
						&& (typeof window.history.pushState == 'function')) {
						window.history.pushState("Updating page URL after new save.",
							me.htmlPageTitle, viewStoryWizardUrl + data.storyResult.articleId + '&type=' + data.storyResult.type);
						this.pageTypeId = data.storyResult.type;
					}
					
					// update content type for fxd gallery after new save.
					var hasGalleryDropDown = document.getElementById('select_story_content_type');
					if(me.oldStoryStatus == 'new' && hasGalleryDropDown && (data.storyResult.type == "gallery" || data.storyResult.type == "list-gallery")) {
						if(data.storyResult.type == "gallery") {
							var contentType = "<span class=\"aui-field-element\" id=\"story_content_type\">Gallery</span>";
							jQuery('#select_story_content_type').replaceWith(contentType);
						}else if(data.storyResult.type == "list-gallery") {
							var contentType = "<span class=\"aui-field-element\" id=\"story_content_type\">ListGallery</span>";
							jQuery('#select_story_content_type').replaceWith(contentType);
						}
					}
				}
				
				jQuery('#statusEdit').show();
				
				if( data.storyResult.lastEditedDateFormatted) {
					$('#storyLastEditDateLabel').text( data.storyResult.lastEditedDateFormatted);
				}
				
				if (data.storyResult.storyTransitionStates) {
					 jQuery('#storyStatesList').find('li').remove().end();
					 jQuery.each(data.storyResult.storyTransitionStates, function(key, value){
						jQuery('#storyStatesList').append( '<li id="' + value.transitionValue + '">' + value.transitionLabel +  '</li>' );
					 });

				}
				
				// Update the distributions
				me.writeDistributionsToPage(data.storyResult.distributionStatus);
				
				//update settings version data
				__WS_StoryMaster.refreshVersionData({version : data.storyResult.currentVersion,
					 updateVersionedFieldsData : false});
				me.currentVersion = data.storyResult.currentVersion;
			
				if (isWorkflowTurnedOn && data.storyResult.storyStatus == 'draft') {
					location.href = viewStoryWizardUrl + data.storyResult.articleId + '&type=' + me.pageTypeId;
				}
								
				this.operation = 'EDIT';
				//alert(message);
				EP.Util.success.alert(message);
			} else {
				var message = '';
				if(data.storyResult.response) {
					console.log('in postSave failure');
					message = message +  data.storyResult.response;
				}
				if(me.storyStatus == 'approved' || me.storyStatus == 'expired') {
					me.scheduleVO.publishBy = me.scheduleVO.oldPublishBy;
					me.scheduleVO.unPublishBy = me.scheduleVO.oldUnPublishBy;
				}
				me.storyStatus = me.oldStoryStatus;
				//alert(message);
				EP.Util.error.alert(message);
			}
			this.UI.updateState();
			if(data.storyResult.storyStatus == 'Purge') {
				window.location.href = this.dashboardUrl;
			}
		}

		$('html').toggleClass('has-pub-schedule', $('#publish_schedule:visible').length > 0);
		$('html').toggleClass('has-unpub-schedule', $('#unpublish_schedule:visible').length > 0);
	};

	proto.storyProxySave = function() {
		var me = this;
		if (isWorkflowTurnedOn)
		{
			$.post( me.formAction, {
				StoryMaster_storyProxyHeadline: me.storyHeadline,
				StoryMaster_storyLayoutId: me.layoutId,
				StoryMaster_siteId: me.siteId,
				StoryMaster_publishBy: me.publishBy,
				StoryMaster_unpublishBy: me.unpublishBy,
				StoryMaster_storyId: me.articleId,
				StoryMaster_storyAction: me.storyAction
			});
		}
	};

	proto.updateLock = function (me, nodes) {
		var lock = me.lock;
		//-- if locked by another user, lock w/ user icon
		if( lock && lock.locked ){
			nodes.btnLock.$.removeClass('lock unlock').addClass('by-user');
			jQuery('.portlet-content-container > .portlet-body').each( function(){
				EP.Util.disableOverlay( this );
			});
			EP.Util.disableOverlay( jQuery('.storyallmaster-portlet .portlet-content-container .portlet-body').get(0), false);
			EP.Util.disableToggle( $('#btn_save'), true );
			EP.Util.disableToggle( $('#btn_publish'), true );
			EP.Util.disableToggle( $('#btn_expire'), true );
			jQuery('#statusEdit').toggle(false);
		} else if(lock && lock.lockId) {
			nodes.btnLock.$.removeClass('unlock by-user').addClass('lock');
			jQuery('.portlet-content-container > .portlet-body').each( function(){
				EP.Util.disableOverlay( this, false );
			});
			EP.Util.disableToggle( $('#btn_save'), false );
			EP.Util.disableToggle( $('#btn_publish'), false );
			EP.Util.disableToggle( $('#btn_expire'), false );
			jQuery('#statusEdit').toggle(true);
		} else {
			if(me.storyStatus != "new") {
				nodes.btnLock.$.removeClass('lock by-user').addClass('unlock');
				jQuery('.portlet-content-container > .portlet-body').each( function(){
					EP.Util.disableOverlay( this );
				});
				EP.Util.disableOverlay( jQuery('.storyallmaster-portlet .portlet-content-container .portlet-body').get(0), false);
				if (!me.sharedByReference) {
					EP.Util.disableToggle( $('#btn_save'), true );
				} else {
					EP.Util.disableToggle( $('#btn_save'), false );
					EP.Util.disableOverlay( jQuery('.category-portlet .portlet-content-container .portlet-body').get(0), false);
					EP.Util.disableOverlay( jQuery('.topics-portlet .portlet-content-container .portlet-body').get(0), false);
				}
				EP.Util.disableToggle( $('#btn_publish'), true );
				EP.Util.disableToggle( $('#btn_expire'), true );
				jQuery('#statusEdit').toggle(false);
			}
		}
		if(lock && lock.lockedBy) {
			nodes.userLockStatus.$.html('Locked by ' + lock.lockedBy + ' at ' + lock.lockedTimeFormatted);
		} else {
			nodes.userLockStatus.$.html('Unlocked');
		}
	};
	
	proto.checkLock = function ( me ) {
		var url = '/story-wizard-portlet/restful/checkLock?articleId='+me.articleId+'&userId='+userId+'&groupId='+groupId;
		EP.io.request(url, {
			data : {
				val : {
					contentType : 'CREATESTORY',
					subType : 'checkLock'
				}
			},
			dataType : 'json',
			method : 'GET',
			sync: true,
			on : {
				success : function() {
					var obj = this.get('responseData');
					me.lock = obj.lock;
				}
			}
		});
	};

	proto.acquireLock = function(me, _nodes) {
		if (me.sharedByReference || me.storyStatus == "new" || me.articleId == "0") {
			return false;
		} else {
			var $btnLock = $(_nodes.btnLock.$);
			var oldLock = me.lock;
			var msgChange = '';
			me.checkLock( me );
			if( (me.lock.locked != oldLock.locked) || (me.lock.lockId != oldLock.lockId) || (me.lock.lockBy != oldLock.lockBy) ) {
				msgChange = '<strong>The page lock has been changed by others.</strong><br/><br/>';
				me.updateLock(me, me.UI.nodes);
			}
			if( $btnLock.hasClass('unlock') || $btnLock.hasClass('by-user') ) {
				me.UI.pageLockingModal.ask({
					msg : $btnLock.hasClass('by-user') ? msgChange+'This Page was ' + _nodes.userLockStatus.$.html() + '.<br/> Do you want to acquire a lock for 	this story page?' : msgChange+'Do you want to acquire a lock for this story page?',
					box : {
						text : 'Keep my changes'
					},
					cancel : {
						text : 'Cancel'
					},
					proceed : {
						text : 'Acquire Lock',
						action : function(checkFlag){
							//direct acquire lock and ignore others modification.
							var url = '/story-wizard-portlet/restful/acquireLock?articleId='+me.articleId+'&asAdmin='+$btnLock.hasClass('by-user')+'&userId='+userId+'&groupId='+groupId;
							EP.io.request(url, {
								data : {
									val : {
										contentType : 'CREATESTORY',
										subType : 'acquireLock'
									}
								},
								dataType : 'json',
								method : 'GET',
								on : {
									success : function() {
										var obj = this.get('responseData');
										me.lock = obj.lock;
										me.updateLock(me, _nodes);
										if(obj.success) {
											EP.Util.success.alert(obj.message||"Lock acquired.");
											if(!checkFlag) {
												//check box not checked, means reload page to fetch updated content
												window.location.reload();
											}
										} else {
											EP.Util.error.alert(obj.message||"Error acquiring lock.");
										}
									}
								}
							});
						}
					},
				});
				return true;
			} else {
				return false;
			}
		}
	};
	
	proto.writeDistributionsToPage = function(distributionStatus) {
		for (var idx in distributionStatus) {
			var station = distributionStatus[idx];
			// Disable the checkbox
			var el1 = jQuery('li[name=' + station.stationName + ']');
			el1.find(".channel").css("color", "#a5a5a5");
			el1.find(":checkbox")
					.prop("disabled", true)
					.prop("checked", true);
			
			// Update the status
			var status =  station.status;
			if (station.status == 'Published')
				status += ' (v' + station.version + ')';
			var button = '';
			if ((station.status != 'Published') && (station.status != 'Accepted'))
				button = '<button><span>x</span></button>';
			var el2 = jQuery('tr[name=' + station.stationName + ']');
			if (el2) {
				el2.find(".action").html("<b>" + status + "</b>" + button);
			}
		}
	};


})( jQuery );
result
package com.endplay.portlets.quickpublish;

import java.io.Serializable;

public class QuickPublishResult implements Serializable {
	boolean success;
	String response;
	private Long pageId;
	//private int type;
	private String type;
	private Long groupId;
	private String headlineString;
	private String statusType;

	public QuickPublishResult(boolean success, String response) {
		// TODO Auto-generated constructor stub
		this.success=success;
		this.response=response;
	}
	
	public boolean getSuccess(){
		return this.success;
	}
	public String getResponse(){
		return this.response;
	}

	public void setSuccess(boolean success){
		this.success=success;
	}
	public void setResponse(String response){
		this.response=response;
	}

	/**
	 * @param pageId the pageId to set
	 */
	public void setPageId(Long pageId) {
		this.pageId = pageId;
	}

	/**
	 * @return the pageId
	 */
	public Long getPageId() {
		return pageId;
	}

	

	/**
	 * @return the type
	 */
	public String getType() {
		return type;
	}

	/**
	 * @param type the type to set
	 */
	public void setType(String type) {
		this.type = type;
	}

	/**
	 * @param groupId the groupId to set
	 */
	public void setGroupId(Long groupId) {
		this.groupId = groupId;
	}

	/**
	 * @return the groupId
	 */
	public Long getGroupId() {
		return groupId;
	}

	/**
	 * @param headlineString the headlineString to set
	 */
	public void setHeadlineString(String headlineString) {
		this.headlineString = headlineString;
	}

	/**
	 * @return the headlineString
	 */
	public String getHeadlineString() {
		return headlineString;
	}

	/**
	 * @param statusType the statusType to set
	 */
	public void setStatusType(String statusType) {
		this.statusType = statusType;
	}

	/**
	 * @return the statusType
	 */
	public String getStatusType() {
		return statusType;
	}

}
control
package com.endplay.portlets.quickpublish;


import com.endplay.portlet.journal.JournalArticleDataConstants;
import com.endplay.portlets.common.CommonCMSDataUtil;
import com.endplay.portlets.common.CommonConstants;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import com.liferay.portal.model.Group;

import java.beans.PropertyEditorSupport;

import javax.servlet.http.HttpServletRequest;

import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/*
 * This is the spring dispatcher controller class that receives the action request 
 * from js clients
 */
@Controller
@RequestMapping("/quickpublish")
public class QuickPublishController {

	public static Log log = LogFactoryUtil.getLog(QuickPublishController.class);
		
	/**
	 * @Title: getAllAuthors
	 * @Description: TODO
	 * @param request
	 * @param quickPublishVO
	 * @return
	 * @throws Exception
	 * @return QuickPublishVO
	*/ 
	@RequestMapping(value = "/getAllAuthors", method = RequestMethod.POST)
	public QuickPublishVO getAllAuthors(HttpServletRequest request, @RequestParam QuickPublishVO quickPublishVO) throws Exception {				
		CommonCMSDataUtil.setCommonPortalProperties(request, quickPublishVO);
		return new QuickPublishWorker().populateAuthors(quickPublishVO);
	}
	
	/**
	 * @Title: getPageDefaults
	 * @Description: if click gallery drop down,then call it.
	 * @param request
	 * @param quickPublishVO
	 * @return
	 * @throws Exception
	 * @return QuickPublishVO
	*/ 
	@RequestMapping(value = "/getPageDefaults", method = RequestMethod.POST)
	public QuickPublishVO getPageDefaults(HttpServletRequest request, @RequestParam QuickPublishVO quickPublishVO) throws Exception {				
		CommonCMSDataUtil.setCommonPortalProperties(request, quickPublishVO);
		new QuickPublishWorker().populateCopyrightsAndCategories(quickPublishVO, null, false);
		return quickPublishVO;
	}
	
	/**
	 * @Title: save
	 * @Description: TODO
	 * @param request
	 * @param quickPublishVO
	 * @return
	 * @throws Exception
	 * @return QuickPublishResult
	*/ 
	@RequestMapping(value = "/save", method = RequestMethod.POST)
	public QuickPublishResult save(HttpServletRequest request, @RequestParam QuickPublishVO quickPublishVO) throws Exception {		
		quickPublishVO.setStatus(WorkflowConstants.LABEL_DRAFT);
		quickPublishVO.setStoryAction(CommonConstants.STORY_ACTION_SAVE);
		return doPublishOrSave(request,quickPublishVO);
	}

	/**
	 * @Title: publish
	 * @Description: TODO
	 * @param request
	 * @param quickPublishVO
	 * @return
	 * @throws Exception
	 * @return QuickPublishResult
	*/ 
	@RequestMapping(value = "/publish", method = RequestMethod.POST)
	public QuickPublishResult publish(HttpServletRequest request, @RequestParam QuickPublishVO quickPublishVO) throws Exception {	
		quickPublishVO.setStatus(WorkflowConstants.LABEL_APPROVED);
		quickPublishVO.setStoryAction(CommonConstants.STORY_ACTION_PUB);
		return doPublishOrSave(request,quickPublishVO);
	}	
	
	/**
	 * @Title: doPublishOrSave
	 * @Description: TODO
	 * @param request
	 * @param quickPublishVO
	 * @return
	 * @throws Exception
	 * @return QuickPublishResult
	*/ 
	private QuickPublishResult doPublishOrSave(HttpServletRequest request,QuickPublishVO quickPublishVO) throws Exception {
		QuickPublishResult quickPublishResult = new QuickPublishResult(false,"");
		try {
			CommonCMSDataUtil.setCommonPortalProperties(request, quickPublishVO);
			QuickPublishManager quickPublishManager = new QuickPublishManager();
			Group group = CommonCMSDataUtil.getGroup(quickPublishVO);
			if (quickPublishVO.getType().equals(JournalArticleDataConstants.TYPE_GALLERY)) {
				quickPublishResult = quickPublishManager.processAndSaveGallery(quickPublishVO, group);
			} else if (quickPublishVO.getType().equals(JournalArticleDataConstants.TYPE_STORY)) {
				quickPublishResult = quickPublishManager.processAndSaveStory(quickPublishVO, group);
			}
		} catch (Exception e) {
			log.error("Error in doPublishOrSave:" + e);
			throw new Exception(e);
		}
		return quickPublishResult;
	}
	
	@InitBinder
	public void initBinder(WebDataBinder binder) {
		binder.registerCustomEditor(QuickPublishVO.class,new QuickPublishJSONPropertyEditor());
	}
	
	protected class QuickPublishJSONPropertyEditor extends PropertyEditorSupport {
		public QuickPublishJSONPropertyEditor() {

		}
		@Override
		public String getAsText() {
			return super.getAsText();
		}

		@Override
		public void setAsText(String arg0) throws IllegalArgumentException {
			// TODO Auto-generated method stub
			log.warn("in set as text " + arg0);
			ObjectMapper mapper = new ObjectMapper();
			// Ignore unknown properties
			mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,false);

			Object value = null;
			try {
				value = mapperReadValue(mapper, arg0);
			} catch (Exception e) {
				log.error("Error in setAsText:" + e);
			}
			setValue(value);
		}
	}
	
	protected Object mapperReadValue(ObjectMapper mapper, String arg0) throws Exception {
		return mapper.readValue(arg0, QuickPublishVO.class);
	}

}
action
package com.endplay.portlets.quickpublish;

import com.endplay.portlet.journal.JournalArticleDataConstants;
import com.endplay.portlets.common.CommonCMSDataUtil;
import com.endplay.portlets.common.Worker;
import com.endplay.portlets.media.MediaVO;
import com.endplay.portlets.media.MediaWorker;
import com.endplay.portlets.story.StoryVO;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.model.Layout;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portal.util.PortalUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

/**
 * Portlet implementation class QuickPublishAction
 */
public class QuickPublishAction extends MVCPortlet {
	
	@Override
	public void doView(RenderRequest renderRequest,
			RenderResponse renderResponse) throws IOException, PortletException {
		// TODO Auto-generated method stub
		ThemeDisplay themeDisplay = (ThemeDisplay) renderRequest.getAttribute (WebKeys.THEME_DISPLAY);
		Layout layout = themeDisplay.getLayout();
		long attributesLayoutId = layout.getPlid();
		String portletId= themeDisplay.getPortletDisplay().getId();
	
		// set layout, portlet and story page id in VO 
		// call worker to populate VO for view
		Worker quickPublishWorker = new QuickPublishWorker();
		QuickPublishVO quickPublishVO = new QuickPublishVO();
		quickPublishVO.setLayoutId(attributesLayoutId);
		quickPublishVO.setPortletId(portletId);
		quickPublishVO.setId(0L);
		quickPublishVO.setRequest(PortalUtil.getHttpServletRequest(renderRequest));
		quickPublishVO.setRenderRequest(renderRequest);
		
		quickPublishVO.setType(JournalArticleDataConstants.TYPE_STORY);
		
		//populate quick pub vo
		try {
			quickPublishVO.setUserId(CommonCMSDataUtil.getUserId(quickPublishVO));
			quickPublishVO.setGroupid(CommonCMSDataUtil.getGroupId(quickPublishVO));
			quickPublishWorker.populateView(quickPublishVO);
		} catch(Exception e) {
			throw new PortletException(e);
		}
		renderRequest.setAttribute("quickPublishVO", quickPublishVO);
		
		//populate media vo
		MediaVO mediaVO = new MediaVO();
		mediaVO.setRequest(PortalUtil.getHttpServletRequest(renderRequest));
		populateMediaAttributes(quickPublishVO, mediaVO);
		renderRequest.setAttribute("mediaVO", mediaVO);
		
		StoryVO storyVO = (StoryVO)quickPublishVO.getStoryVO();
		renderRequest.setAttribute("storyVO", storyVO);
		
		//page types
		Map<String, String> pageTypes = new HashMap<String, String>();

		pageTypes.put(JournalArticleDataConstants.TYPE_STORY,"Story");
		pageTypes.put(JournalArticleDataConstants.TYPE_GALLERY,"Gallery");
		renderRequest.setAttribute("pageTypes", pageTypes);
		
		super.doView(renderRequest, renderResponse);
	}

	private MediaVO populateMediaAttributes(QuickPublishVO quickPublishVO, MediaVO mediaVO) {
		// call worker to populate VO for view
		MediaWorker mediaWorker = new MediaWorker();
		mediaVO.setId(0L);
		mediaVO.setLayoutId(quickPublishVO.getLayoutId());		 
		mediaWorker.populateView(mediaVO);		
		return mediaVO;
	}
}	
JSP2
<%@ include file="/jsp/init.jsp" %>
<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>

<!--<script src="${pageContext.servletContext.contextPath}/js/quickpublish/javascript.js${STATIC_FILE_SUFFIX}"></script>-->
<link href="${pageContext.servletContext.contextPath}/css/quickpublish/portlet.css${STATIC_FILE_SUFFIX}" rel="stylesheet" type="text/css" />
<script src="${pageContext.servletContext.contextPath}/js/quickpublish/QuickPublish.js${STATIC_FILE_SUFFIX}"></script>

<%@page import="com.liferay.portal.kernel.util.WebKeys" %>
<%@page import="com.liferay.portal.model.Layout" %>
<%@page import="com.liferay.portal.theme.ThemeDisplay" %>
<%@page import="com.endplay.portlets.quickpublish.QuickPublishVO"%>
<%@page import="com.endplay.portlets.attributes.CopyrightVO"%>
<%@page import="com.endplay.portlets.category.CategoryItemVO"%>
<%@page import="com.endplay.portlets.story.StoryVO"%>
<%
	QuickPublishVO quickPubAttributes = (QuickPublishVO)renderRequest.getAttribute("quickPublishVO");
	StoryVO storyVO = (StoryVO)quickPubAttributes.getStoryVO();
	HashMap<Integer, String> pageTypes = (HashMap<Integer, String>)renderRequest.getAttribute("pageTypes");	
	long quickPublishLayoutId = quickPubAttributes.getLayoutId();
%>


		<div class="block">
		<!-- page type :: might have to be populated from somewhere -->
		<span class="aui-field">
            <span class="aui-field-content">
                <label class="aui-field-label">Type:</label>
                <span class="aui-field-element">
		            <select class="aui-field-input aui-field-input-select" id="acc_page_type" name="acc_page_type">
						<!--  <option value="300">Story</option>			
						<option value="9999">Image Gallery</option> -->
						<%
							for(Map.Entry<Integer, String> pageType : pageTypes.entrySet() ){		
						%>		
		            			<option value="<%=pageType.getKey() %>" class="<%= pageType.getValue()%>"><%= pageType.getValue()%></option>								            		 
		            	<%
		            		}
		            	%>
		            </select>
				</span>
            </span>
        </span>
		<!-- <div class="block acc_story_attributes" style="display:none">-->
		<div class="acc_flags acc_story_attrs_toggle acc_load_block" style="margin:-40px 0 0 190px; display:none">
        <!--Breaking News  Flag-->                  
        <!--Alert Flag  -->        
		<span class="aui-field">
            <span class="aui-field-content">
            	<label class="aui-field-label" style="padding:0 0 4px 100px;">Breaking News:</label>
                <span class="aui-field-element">
                    <input class="aui-field-input aui-field-input-checkbox" type="checkbox" id="acc_quick_breaking" />
                </span>
                <label class="aui-field-label" style="width:35px;">Alert:</label>
                <span class="aui-field-element">
                    <input class="aui-field-input aui-field-input-checkbox" type="checkbox" id="acc_quick_alert" />
                </span>				
            </span>
        </span>		 
        </div>	
		<!-- <div> -->
		<!-- headline -->
		<div class="acc_load_block" style="display:none">
			<span class="aui-field aui-field-row">			
                    <span class="aui-field-content">
                        <label class="aui-field-label">Headline<i>*</i>:</label>
                        <meter min="0" max="100" value="0"><span></span>/100</meter>
                        <div class="aui-field-element full-width">
                            <input class="aui-field-input aui-field-input-text metered acc_hide_all" id="acc_headline" maxlength="100" required="required" type="text" />
                        </div>
                    </span>
            </span>
		</div>	
		</div>								
		<div class="block acc_story_attributes" style="display:none">
			<span class="aui-field aui-field-row">			
				<span class="aui-field-content">
					<label class="aui-field-label">Short Headline:</label>
					<meter min="0" max="<%=storyVO.getShortHeadlineMaxCount() %>" value="0"><span></span>/<%=storyVO.getShortHeadlineMaxCount() %></meter>
					<div class="aui-field-element full-width">
						<input class="aui-field-input aui-field-input-text metered acc_image_hide" id="acc__short_headline" maxlength="<%=storyVO.getShortHeadlineMaxCount() %>" required="required" type="text" />
					</div>
				</span>
			</span>
			
			<div class="acc_story_attrs_toggle" style="display:block">
			<!--Dateline  -->
			<span class="aui-field aui-field-row">			
				<span class="aui-field-content">
					<label class="aui-field-label">Dateline:</label>
					<meter min="0" max="40" value="0"><span></span>/40</meter>
					<div class="aui-field-element">
						<input class="aui-field-input aui-field-input-text metered acc_image_hide" id="acc_dateline" maxlength="40" type="text" />
					</div>
				</span>
			</span>
			<!--Story Body  -->
			<span class="aui-field aui-field-row">
            	<span class="aui-field-content">
                	<label class="aui-field-label">Story Body:</label>
                	<div class="aui-field-element">
                		<textarea id="acc_story_body" class="aui-field-input aui-field-input-text aui-field-input-textarea cke-replace" name="input_story-body"></textarea>
                	</div>
           	 	</span>
        	</span>
        	</div>
			<!-- short-headline -->
			<div class="acc_gallery_attrs_toggle" style="display:none">
			<!--  <span class="aui-field aui-field-row">			
				<span class="aui-field-content">
					<label class="aui-field-label">Short Headline <i>*</i></label>
					<meter min="0" max="100" value="0"><span></span>/100</meter>
					<div class="aui-field-element full-width">
						<input class="aui-field-input aui-field-input-text metered acc_image_hide" id="acc__short_headline" maxlength="100" required="required" type="text" />
					</div>
				</span>
			</span>-->
			<!-- Abstract -->
			<span class="aui-field aui-field-row acc_abs_span">
                    <span class="aui-field-content">
                        <label class="aui-field-label">Abstract:</label>
                        <meter min="0" max="500" value="0"><span></span>/500</meter>
                        <div class="aui-field-element">
                            <textarea class="aui-field-input aui-field-input-text metered" id="acc_story_abs" name="acc_story_abs"></textarea>
                        </div>
                    </span>
            </span>
			</div>
		<!-- page default :: need to populate with defaults from back end. -->				
		<span class="aui-field">
            <span class="aui-field-content">
                <label class="aui-field-label">Page Default:</label>
                <span class="aui-field-element">
		            <select class="aui-field-input aui-field-input-select" id="acc_pagedefault">
		            	<c:if test="<%= quickPubAttributes.getCategoryVOs() != null %>">
			            	<%
			            		for(CategoryItemVO category : quickPubAttributes.getCategoryVOs() ) {
			            	%>
			            			<option value="<%=category.getCategoryid() %>"><%= category.getMyLabel()%></option> 
			            	<%
			            		}
			            	%>
		            	</c:if>
		            </select>
            </span>
            </span>
        </span>	
		<div class="acc_story_attrs_toggle" style="display:block">
		
		<!-- Author info :: mostly logged in user -->		
		 <span class="aui-field acc_author_temp" style="display: none;">
            <span class="aui-field-content">
                <label class="aui-field-label acc_author_title">Author:</label>
                <span class="aui-field-element">
		          <select class="aui-field-input aui-field-input-select acc_getoptions" id="acc_author">
					<option>None</option>
				  </select>  				  
            </span>
            </span>
        </span> 
		<!-- TEST AUTO-COMPLETE-->				
		<span class="aui-field aui-field-row acc_author_auto">			
                    <span class="aui-field-content">
                        <label class="aui-field-label acc_author_title">Author:</label>                
                        <div id="acc_author_auto"></div>
                    </span>
        </span>
		<ul class="acc_author_results sortable-list">
		</ul>

		<!-- Copyright :: default value or drop down ?-->
		<span class="aui-field">
            <span class="aui-field-content">
                <label class="aui-field-label">Copyright:</label>
                <span class="aui-field-element">
		            <select class="aui-field-input aui-field-input-select" id="acc_copyright" name="acc_copyright">
		            	<%
		            		for(CopyrightVO copyright : quickPubAttributes.getAttributesVO().getCopyrightVOs() ) {
		            	%>
		            			<option value="<%=copyright.getCopyrightId() %>" 
			            			<% if(copyright.isSelected()) {
			            					%>selected="selected" <%
									}%>
								><%= copyright.getCopyrightPrefixString()%></option> 
		            	<%
		            		}
		            	%>
		            </select>
            </span>
            </span>
        </span>
		<!-- Custom Copyright -->
		<span class="aui-field-row acc_custom_copyright_field" style="display:none;">			
				<span class="aui-field-content">					
					<div class="aui-field-element">
						<input class="aui-field-input aui-field-input-text" id="acc_custom_copyright" type="text"/>
					</div>
				</span>
		</span>
        
        <!--Breaking News  Flag-->
        <!-- 
		<span class="aui-field">
            <span class="aui-field-content">
                <label class="aui-field-label">Breaking News:</label>
                <span class="aui-field-element">
                    <input class="aui-field-input aui-field-input-checkbox" type="checkbox" id="acc_quick_breaking" />
                </span>
            </span>
        </span>
         -->
        <!--Alert Flag  -->
        <!-- 
		<span class="aui-field">
            <span class="aui-field-content">
                <label class="aui-field-label">Alert Feed:</label>
                <span class="aui-field-element">
                    <input class="aui-field-input aui-field-input-checkbox" type="checkbox" id="acc_quick_alert" />
                </span>
            </span>
        </span>
		 -->
		</div>
		</div>
JSP1
<%--
/**
* Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
--%>
<%@ include file="/jsp/init.jsp" %>

<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>

<!--<script src="${pageContext.servletContext.contextPath}/js/quickpublish/javascript.js${STATIC_FILE_SUFFIX}"></script>-->

<script src="${pageContext.servletContext.contextPath}/js/quickpublish/QuickPublish.js${STATIC_FILE_SUFFIX}"></script>

<!--<style type="text/css">

h2.acc_trigger {
	padding: 0;	margin: 0 0 5px 0;
	background: url("${pageContext.servletContext.contextPath}/images/media/accordian_img.gif") no-repeat;	
	height: 46px;	
	line-height: 46px;
	width: 500px;
	font-size: 2em;
	font-weight: normal;
	float: left;
}

</style> -->

<%@page import="com.liferay.portal.kernel.util.WebKeys" %>
<%@page import="com.liferay.portal.model.Layout" %>
<%@page import="com.liferay.portal.theme.ThemeDisplay" %>
<%@page import="com.endplay.portlets.quickpublish.QuickPublishVO"%>
<%@page import="org.codehaus.jackson.JsonFactory"%>
<%@page import="org.codehaus.jackson.map.ObjectMapper"%>
<%@page import="com.endplay.portlets.distribution.DistributionVO"%>

<%
	QuickPublishVO quickPubAttributes = (QuickPublishVO)renderRequest.getAttribute("quickPublishVO");	
	long quickPublishLayoutId = quickPubAttributes.getLayoutId();
	Map<String, String> paramMap = new HashMap<String, String>();
	paramMap.put("type","QuickPublish");	
	renderRequest.setAttribute("params", paramMap);
	DistributionVO distributionVO = quickPubAttributes.getStoryVO().getDistributionVO();
	ObjectMapper mapper = new ObjectMapper(new JsonFactory());
%>

<script type="text/javascript">
var allAuthorsEndPoint = '<%=(String) renderRequest.getPreferences().getValue("AllAuthorsEndPoint", "") %>';
var pageDefaultsEndPoint = '<%=(String) renderRequest.getPreferences().getValue("pageDefaultsEndPoint", "") %>';
var saveEndPoint = '<%=(String) renderRequest.getPreferences().getValue("QuickSaveEndPoint", "") %>?userId='+userId+'&groupId='+groupId;
var publishEndPoint = '<%=(String) renderRequest.getPreferences().getValue("QuickPublishEndPoint", "") %>?userId='+userId+'&groupId='+groupId;
var quickPublishLayoutId = <%=quickPublishLayoutId%>;
var galleryDefaults;
var storyDefaults;
var storyPortletConfig =  {distributionVO : <%= mapper.writeValueAsString(distributionVO)%>};
</script>
<div class="xyz_container">
	<h2 class="acc_trigger active"><a href="#"><span class="icon-arrow-down">▼</span><span class="icon-arrow-right">►</span> <text class="acc_type">Quick Story</text></a></h2>
	<form name="storyForm" id="storyForm">
	<div class="acc_container">	
		<c:import url="story-view.jsp"/>	
	</div>	
	</form>
	<h2 class="acc_trigger acc_media_tab collapsed" style="display:none"><a href="#"><span class="icon-arrow-down">▼</span><span class="icon-arrow-right">►</span> Quick Media</a></h2>
	<div class="acc_container" style="display:none">
		<div class="block">
			<!-- <input type="button" value="Load Image Data" class="btn-text" id="acc_loadData"> -->
			<div class="std-datatable"><c:import url="../media/view.jsp"/></div>
		</div>
	</div>	
	<h2 class="acc_trigger collapsed" style="display:none"><a href="#"><span class="icon-arrow-down">▼</span><span class="icon-arrow-right">►</span> Quick Share/Distribution</a></h2>
	<div class="acc_container" style="display:none">
		<div class="block">
			<c:import url="../story/tab_distribution.jsp" />
		</div>
	</div>	
</div>

<!-- FOOTER publish and other buttons-->
<footer class="acc_footer" style="display:none"> 
	<button class="btn btn-text btn-gradient" id="acc_save">Save Draft</button>
	<button class="btn btn-text btn-gradient" id="acc_reset">Reset</button>
	<button class="btn btn-text btn-gradient btn-gradient_green" id="btn_acc_publish">Publish</button>
	<div class="acc_result block" style="display:none">
	 test
	</div>
</footer>	

<!-- <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js${STATIC_FILE_SUFFIX}"></script> -->
<script type="text/javascript">		

jQuery(document).ready(function($){
//$(".acc_container").hide();
//$(".acc_trigger").hide(); 
//$(".acc_footer").hide();
//$('.acc_trigger:first').show();
//$('.acc_trigger:first').addClass('active').next().show();
//accordian function
//select story by default
$('.Story').attr("selected","selected");
$('.acc_trigger').click(function(){
	//$('.acc_trigger').addClass('collapsed');
	if( $(this).next().is(':hidden') ) { 
		$('.acc_trigger').removeClass('active').next().slideUp(); 
		$(this).toggleClass('active').next().slideDown();
		$('.acc_trigger').addClass('collapsed');
		$(this).removeClass('collapsed');	
	}	
	return false; //Prevent the browser jump to the link anchor
});
//show other tabs and other fields on headline key down.
$('.acc_hide_all').keydown(function(){
	if($(this).hasClass('acc_hide_all')){	
		$(this).removeClass('acc_hide_all');
		//show other attributes		
		$(".acc_story_attributes").slideDown(); 
		//$(".acc_flags").slideDown(); 
		//show other tabs
		$(".acc_trigger").slideDown(); 
		$(".acc_footer").slideDown();
		//quickpublish.js to init the editor.
		initCkeditor('acc_story_abs');
		initCkeditor2('acc_story_body');
		swapTemplatePageType();
		//saveStoryPageDefaults();
		//get authors
		var authorUrl = window.location.protocol + '//'+ window.location.hostname + ':'+ window.location.port + allAuthorsEndPoint;
		getAllAuthors(quickPublishLayoutId, authorUrl);
		
	}
});
//change page type
$('#acc_page_type').change(function(){
	swapTemplatePageType();
	var url = window.location.protocol + '//'+ window.location.hostname + ':'+ window.location.port + pageDefaultsEndPoint;
	var type = $('select[name=acc_page_type]').val();
	swapPageDefault(quickPublishLayoutId, url, type);
});

//change Copyright type
$('#acc_copyright').change(function(){			
	swapCopyright();
});

//get authors on author key down acc_author_auto
/*$('#acc_author').click(function(){
var url = window.location.protocol + '//'+ window.location.hostname + ':'+ window.location.port + allAuthorsEndPoint;
if($(this).hasClass('acc_getoptions')){	
	$(this).removeClass('acc_getoptions');	
	getAllAuthors(quickPublishLayoutId, url);		
}
});*/

//handle save click
$('#acc_save').click(function(){
	var url = window.location.protocol + '//'+ window.location.hostname + ':'+ window.location.port + saveEndPoint;
	read(url);
});
//handle publish click
$('#btn_acc_publish').click(function(){
	var url = window.location.protocol + '//'+ window.location.hostname + ':'+ window.location.port + publishEndPoint;
	read(url);
});

//handle reset
$('#acc_reset').click(resetFields);
});

//wait and open headline
load();

</script>	




JS
var initCkeditor;
var activityConfig;


( function($){

var meterAbstract1, updatemeter1;
var firstCall = true;

initCkeditor = function(id) {
if( document.getElementById(id) != null){
		var CK_Abstract = CKEDITOR.replace(
			id,
			{
				filebrowserBrowseUrl: null,
				filebrowserUploadUrl: null,
				toolbar: 'Abstract'
			}
		);
		
		CK_Abstract.on("instanceReady", function(event){
			 meterAbstract1( CK_Abstract, id);
		});
	}	
};

initCkeditor2 = function(id) {
	var test = new EP.Util.createCKEditor({

		node : document.getElementById('acc_story_body'),
		ckConfig : {
						filebrowserBrowseUrl: null,
						filebrowserUploadUrl: null,
						toolbar: 'Body',
						resize_enabled: false
					}
	});	
};


meterAbstract1 = function ( ckeObj, id){
			var xyz = '#'+id;
				if( $(xyz).hasClass('metered') ){											
					var $this = $(xyz),
						$parent = $this.parents('.aui-field-content'),
						$meter = $parent.children('meter');
					
					ckeObj.document.on('keyup', function(){
						count = CKEDITOR.getHTML(id).length;
						
						//-- update meter values
						EP.Util.updateMeter( $meter, count );
					});
					ckeObj.document.on('mousemove', function(){
						count = CKEDITOR.getHTML(id).length;
						
						//-- update meter values
						EP.Util.updateMeter( $meter, count );
					});
				}
}

getAllAuthors = function(quickPublishLayoutId, url){
		AUI().use(
			'aui-io-request',
			function(A) {
				var quickPublishVO = {"layoutId":quickPublishLayoutId};
				quickPublishVO.userId = userId;
				quickPublishVO.groupId = groupId;								
				A.io.request(url, {
					dataType : 'json',
					data : 'quickPublishVO='+JSON.stringify(quickPublishVO),
					method : 'POST',					
					on : {
						success : function() {													
							var options = '';
							var authors = this.get('responseData').quickPublishVO.attributesVO.authors;
							var authors1 = new Array();
							for (var i = 0; i < authors.length; i++) {
								options += '<option value="' + authors[i].authorId + '">' + authors[i].authorLastName + ' ' + authors[i].authorFirstName + '</option>';
								authors1[i] = [authors[i].authorId, authors[i].authorLastName + ' ' + authors[i].authorFirstName];
							}							
							//$('#acc_author').html(options);
							//$('.acc_author_temp').hide();
							//$('.acc_author_auto').show();
							accAutoComplete(authors1);								
						}
					}
				});
			});
}

quickSave = function(quickPublishVO, url){
		renderResult("Processing...");	
		EP.Util.saveDialog.show();		
		AUI().use(
			'aui-io-request',
			function(A) {
//				var quickPublishVO = {"layoutId":quickPublishLayoutId};
				A.io.request(url, {
					dataType : 'json',
					data : 'quickPublishVO='+encodeURIComponent(JSON.stringify(quickPublishVO)),		
					method : 'POST',					
					on : {
						success : function() {													
							//write sucess
							var success = this.get('responseData').quickPublishResult.success;
							var result = this.get('responseData').quickPublishResult.response;
							var pageId = this.get('responseData').quickPublishResult.pageId;
							var groupsId = this.get('responseData').quickPublishResult.groupId;
							var type = this.get('responseData').quickPublishResult.type;
							var statusType = this.get('responseData').quickPublishResult.statusType;
							var headlineString = this.get('responseData').quickPublishResult.headlineString;
							var message = '';
							var statusLink = '<span style="background-color: #3F3E3D; color: #FFFFFF; font-weight: bold; padding: 3px 6px;"> Saved </span>';
							if(success){
								result = result;
								//alert(result);
								renderResult(result);
								resetFields();	
								var pageTypeStr = 'Story';															
								if(pageId) {
									if (type && (type == 'gallery')) {
										pageTypeStr = 'Gallery';
									}
									if(statusType == 'approved'){
										statusLink = '<span style="background-color: #349405; color: #FFFFFF; font-weight: bold; padding: 3px 6px;"> Published </span>';
									}																	
									message = message 
										+ '<text style="font: bold 14px Arial;"> '+pageTypeStr+' Headline : </text>' + headlineString + ' </br>'
										+ '<text style="font: bold 14px Arial;"> '+pageTypeStr+' Page ID : </text>' + pageId + ' </br>'
										+ '<text style="font: bold 14px Arial;">Has been </text>' + statusLink +'</br>';	
								}
								EP.Util.success.alert(message);
							}else{
								message = result;
								EP.Util.error.alert(message);
							}																																	
							EP.Util.saveDialog.hide();
							
						}
					}
				});
			});
		
}

accAutoComplete = function(data){
		AUI().use(
			'aui-autocomplete', 
			function(A){
				var instance = new A.AutoComplete({					
					dataSource: data,
					schema: {resultFields: ['id', 'name']},
					matchKey: 'name',
					delimChar: ',',
					typeAhead: false,
					maxResultsDisplayed: 100, 
					contentBox: '#acc_author_auto',
					on: {
						//on select remove the auto select and show the selection.
						itemSelect: function(e){
							//alert(this.inputNode.val());							
							this.inputNode.val('');
							removeButton = document.createElement('button');
							removeButton.innerHTML = "x";
							removeButton.className = "btn btn-remove";							
							var newAuthor =  '<li class="acc_author_list"'+'id='+ e._resultData.id+ '>'+ e._resultData.name+'</li>';
							$('.acc_author_results').html(newAuthor);
							$('.acc_author_list').append(removeButton);	
							$('#acc_author_auto').hide();	
							$('.acc_author_list .btn').bind('click', function(){								
								$('.acc_author_list').remove();								
								$('#acc_author_auto').show();									
								return false;
							});
						},
						containerExpand:function(e){
							//removing inline width style
							this.overlay.set('width', '');
						}
					}
				}).render();
			});
}

renderResult = function(result){
	$(".acc_result").slideDown();
	$(".acc_result").html(result);	
	$.wait( function(){ $(".acc_result").fadeOut("slow") }, 18);
}

load = function(){
	$.wait( function(){ $(".acc_load_block").slideDown() }, 2);
}

$.wait = function( callback, seconds){
   return window.setTimeout( callback, seconds * 1000 );
}

resetFields = function(){
	//reset all fields
	$('#storyForm').get(0).reset();
	//meter update
	EP.Util.updateMeter($('meter'), 0 );
	//change default
	//$('#acc_page_type').trigger('change');
	swapTemplatePageType();
	swapPageDefault();
	
	//reset ckeditor
	CKEDITOR.instances[ 'acc_story_abs' ].setData('');
	CKEDITOR.instances[ 'acc_story_body' ].setData('');
	//update counters
	EP.Util.updateMeter( $('.acc_story_attributes').children('meter'), 0 );
	$('.acc_author_list').remove();								
	$('#acc_author_auto').show();
	$('#distribution button[name="clear-all"]').trigger('click');
	
	//-- reset Media
	__WS_Media.mediaVO.UI.collectionObj.clearColln(); //-- clear collection object
	__WS_Media.mediaVO.UI.updateUIStatus();
	if(__WS_Media.mediaVO.UI.$addMedia){
		__WS_Media.mediaVO.UI.$addMedia.find('.portlet-nav ul li:eq(0) a').trigger('click'); //-- reselect first tab
	}	
	__WS_Media.mediaVO.UI.$mediaCollection.find('.collection tbody tr').remove(); //-- clear UI
	$('.acc_container #add-media .portlet-nav-content tr').removeClass('selected'); //-- reset search result selection states
}

swapTemplatePageType = function(){
	if($('#acc_page_type option:selected').text() == 'Story'){
		$('.acc_gallery_attrs_toggle').slideUp().attr('STYLE','display:none;');
		$('.acc_story_attrs_toggle').slideDown();
		$('.acc_type').html('Quick Story');
		$('#add-media a[name="videos"]').show();
		//$('#add-media a[name="html"]').show();
		//$('#add-media a[name="interactive"]').show();
		//$('#add-media a[name="poll"]').show();
	}else{
		$('.acc_gallery_attrs_toggle').slideDown();
		$('.acc_story_attrs_toggle').slideUp();
		$('.acc_type').html('Quick Gallery');
		$('#add-media a[name="videos"]').hide();
		//$('#add-media a[name="html"]').hide();
		//$('#add-media a[name="interactive"]').hide();
		//$('#add-media a[name="poll"]').hide();
	}	
}

saveStoryPageDefaults = function(){
	storyDefaults = $('#acc_pagedefault').html();
}

swapPageDefault = function(quickPublishLayoutId, url, typeId){		
	var typeText = $("#acc_page_type option:selected").text();
	//make the ajax call for gallery defaults	
	if(typeText == 'Gallery'){
		if(firstCall){
			firstCall = false;
			saveStoryPageDefaults();  //if first select Gallery.
			$("#acc_pagedefault option").remove();				
			getGalleryPageDefaults(quickPublishLayoutId, url, typeId);
		}else{
			$("#acc_pagedefault option").remove();	
			$("#acc_pagedefault").html(galleryDefaults);
		}		
	} else{
		$("#acc_pagedefault option").remove();	
		$("#acc_pagedefault").html(storyDefaults);
	}
	handleMediaOpen(typeId);	
}

getGalleryPageDefaults = function(quickPublishLayoutId, url, typeId){
		AUI().use(
			'aui-io-request',
			function(A) {
				var quickPublishVO = {"layoutId":quickPublishLayoutId, "type":typeId};
				quickPublishVO.userId = userId;
				quickPublishVO.groupId = groupId;				
				
				A.io.request(url, {
					dataType : 'json',
					data : 'quickPublishVO='+JSON.stringify(quickPublishVO),
					method : 'POST',					
					on : {
						success : function() {																				
							var pageDefaults = this.get('responseData').quickPublishVO.categoryVOs;		
							if (pageDefaults != null) {
								for (var i = 0; i < pageDefaults.length; i++) {
									$('#acc_pagedefault').append($('<option></option>').val(pageDefaults[i].categoryid).html(pageDefaults[i].myLabel));
								}
								$('#acc_pagedefault').removeAttr("disabled");
								galleryDefaults = $('#acc_pagedefault').html();
							}
							return false;	
						}
					}
				});
			});
}

/*prePopulateActivityFeed = function(quickPublishVO){
	activityConfig = {
		userId: userId, 
		groupId: userGroupId,		
		postSharedChannels: quickPublishVO.storyVO.distributionVO.channels,
		preSharedChannels: quickPublishVO.storyVO.distributionVO.channels
	};
	
}*/

/*callActivityFeed = function(pageId, pageType){
	if(pageType == 'Gallery'){
		activityConfig.postGalleryPageId = pageId;
		activityConfig.preGalleryPageId = 0; 
		EP.ActivityFeed.Util.addGalleryActivity(activityConfig);
	}else if(pageType == 'Story'){
		activityConfig.postStoryPageId = pageId;
		activityConfig.preStoryPageId = 0; 
		EP.ActivityFeed.Util.addStoryActivity(activityConfig);
	}
}*/

handleMediaOpen = function(type){	
	if(type == 'Gallery'){
		//click event		
		if(__WS_Media.mediaVO.UI.$addMedia){
			__WS_Media.mediaVO.UI.$addMedia.find('.portlet-nav ul li:eq(1) a').trigger('click'); //-- select photo tab
		}
	}
}

read = function(url){
	//read from feilds
	var headline = $('#acc_headline');
	var shortHeadline = $('#acc__short_headline');
	var dateline = $('#acc_dateline');
	var breakingNews =$('#acc_quick_breaking').is(':checked');
	var alertFeedFlag =$('#acc_quick_alert').is(':checked');
	//alert(breakingNews);
	var pageName = $('#acc_page_name');
	var pageTitle = $('#acc_page_title');
	var pagetype = $('select[name=acc_page_type]');
	var abs = CKEDITOR.getHTML('acc_story_abs');
	var body = CKEDITOR.getHTML('acc_story_body');
	var pagedefault = $('#acc_pagedefault').val();
	var pagedefaultlable = $("#acc_pagedefault option:selected").text();
	//var author = $('#acc_author').val();
	var author1 = $('.acc_author_list').attr('id');
	var copyright = $('#acc_copyright').val();
	var media = __WS_Media.read();	
	var dist = __WS_Dist.read();
	var level = 0;
	if (pagedefault != null) {
		level = pagedefault.slice(0,1);
	}
	var customCopyright = $('#acc_custom_copyright').val();
	//alert('author1'+author1);
	//create obj
	var quickPublishVO;
	var typeText = $("#acc_page_type option:selected").text();
	if(typeText == 'Gallery'){
		quickPublishVO = {
		"layoutId": quickPublishLayoutId,
		"type": pagetype.val(),
		"storyVO": { "headline": $.trim(headline.val()), 
					"storyAbstract": $.trim(abs),
					"shortHeadline": $.trim(shortHeadline.val()),
					//"pageName": pageName.val(),
					//"pageTitle": pageTitle.val(),
					"settingsVO": [],
					"distributionVO":dist.distributionVO},
		"categoryVOs": [ { "id": pagedefault, "myLabel": pagedefaultlable, "level": level},],	
		"mediaVO": media
		};
		var newSettings = new settingsVO(pageName.val(), pageTitle.val());			
		quickPublishVO.storyVO.settingsVO = newSettings;
	}else{
		quickPublishVO = {
		"layoutId": quickPublishLayoutId,
		"type": pagetype.val(),
		"storyVO": { "headline": $.trim(headline.val()),
					"shortHeadline": $.trim(shortHeadline.val()),	
					"dateline": $.trim(dateline.val()),
					"storyBody": $.trim(body),
					"distributionVO":dist.distributionVO},
		"categoryVOs": [ { "id": pagedefault, "myLabel": pagedefaultlable, "level": level},],	
		"mediaVO": media,
		"attributesVO": {
			"copyrightVOs":[{"copyrightId": copyright},],
			//"authors":[{ "authorId": author1 },],
			"authors":[],
			"breakingNews": breakingNews,
			"alertFlag": alertFeedFlag,
			"customCopyright": customCopyright
		}
	};
	if(author1){
		var newAuthor = new author(author1);	
		quickPublishVO.attributesVO.authors.push(newAuthor);//"20921299";
	}
	}		
	//prePopulateActivityFeed(quickPublishVO);
	quickSave(quickPublishVO, url);	
}

author = function(temp){
	this.authorId = temp;
}

settingsVO = function(temp1, temp2){
	this.pageName = temp1;
	this.pageTitle = temp2;
}

swapCopyright = function(){
	var type = $('#acc_copyright option:selected').text();
	if(type == 'Custom'){
		$('.acc_custom_copyright_field').slideDown();
	}else{
		$('.acc_custom_copyright_field').slideUp();
		$('#acc_custom_copyright').val('');
	}
}
		
})( jQuery );
d
http://www.theindychannel.com/
网址
二维码:http://www.mycodes.net/48/4972.htm
http://zhidao.baidu.com/question/51241414.html 
省份证:http://www.mycodes.net/48/5022.htm
life
http://javalibs.blogspot.com/2010/09/liferay-6-scheduler-engine-design.html
2012-12-17 16:57:57
LayOut:http://www.huqiwen.com/2012/09/25/liferay-6-1-development-study-7-layout/ 
建网站:http://wordpress.org/ 
drool,xpath
http://wenku.baidu.com/view/dedd1b1555270722192ef7de.html

http://jiangzhengjun.iteye.com/blog/483048
waiyu
原文:http://www.tianya.cn/publicforum/content/english/1/121795.shtml 

http://loveguchun.appspot.com/
http://loveguchun.appspot.com/moban_html/index.html
Global site tag (gtag.js) - Google Analytics