
package cust.cm_report;

import java.io.*;
import java.util.Vector;
import java.util.*;
import wt.fc.*;
import wt.inf.container.*;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.folder.*;
import wt.util.*;
import wt.pom.Transaction;
import wt.pdmlink.PDMLinkProduct;
import wt.admin.AdminDomainRef;
import wt.admin.AdministrativeDomain;
import wt.admin.AdministrativeDomainServerHelper;
import wt.admin.AdministrativeDomainHelper;
import wt.admin.AdministrativeDomain;
import wt.lifecycle.State;
import wt.inf.team.ContainerTeam;
import wt.project.Role;
import wt.org.WTGroup;
import wt.org.WTPrincipal;
import wt.org.WTPrincipalReference;
import com.ptc.core.domain.admin.common.impl.DomainAdministratorHelper;
import wt.access.AccessPermission;
import com.ptc.core.meta.common.TypeIdentifier;
import com.ptc.core.meta.common.TypeIdentifierUtilityHelper;
import com.ptc.core.meta.server.TypeIdentifierUtility;
import com.ptc.core.meta.type.admin.common.impl.TypeAdminServiceIfcFwd;
import wt.type.TypedUtilityServiceHelper;
import wt.type.TypeDefinitionReference;
import wt.type.TypedUtilityService;
import wt.type.*;
import com.ptc.windchill.enterprise.copy.server.CoreMetaUtility;

public class FolderUtil_01 {

	private static boolean VERBOSE = false;
	private static String subfolders = "";
	private static String DELIM_3RD_FOLDER = ";";
	private static String DELIM_3RD_AND_4ST = ":";
	private static String DELIM_4ST_FOLDER = ",";

	static
	{
		try {
			VERBOSE = (WTProperties.getLocalProperties()).getProperty("ext.fih.pdmlink.projectlinkutil.verbose", false);
			subfolders = (WTProperties.getLocalProperties()).getProperty("ext.fih.pdmlink.folder.subfolder", "CAD:2D Drawing,3D Model,EMX,Document;CAM:CNC,WE,EDM;Document;MoldFlow");
		}

		catch(Throwable throwable) {
			throw new ExceptionInInitializerError(throwable);
		}
	}

	/**
	* @param containerName ???
	* @param productName ??
	* @param moldNoVt ??
	* @return message ??
	*/
	public static String createFolders(String containerName, String productName, Vector moldNoVt) throws WTException {
		String msg = "";

		//parse properties
		Vector subfolderVt = new Vector(); //3rd subfolder and 4st subfolder
		parseProperties(subfolderVt);
		Hashtable ht = getAccessProperites();
		Vector domains = (Vector)ht.get("domains");

		if(VERBOSE)
			System.out.println("ACCESS RULE IS\n\r" + ht);

		//get product container by name
		PDMLinkProduct product = getPDMLinkProductByName(containerName);
		if (product == null) {
			msg = "Can't find product '"+containerName+"'.";
			return msg;
		}

		if (VERBOSE)
			System.out.println(">>"+containerName+" --> "+product.getIdentity());

		//check end item name
		WTContainerRef containerRef = WTContainerRef.newWTContainerRef(product);
		SubFolder folder = null;

		try {
			Folder tempfolder = ext.fih.mes.DocumentUtil.getFolder("/Default/"+productName, (WTContainer)containerRef.getObject());
			folder = (SubFolder)FolderHelper.service.getFolder("/Default/"+productName, containerRef);
		}

		catch (Exception e) {
			msg = "Can't find folder '"+productName+"' in product '"+product.getName()+"'.";
			e.printStackTrace();
			return msg;
		}

		if (VERBOSE)
		System.out.println(">>"+productName+" --> "+folder.getIdentity());

		//create subfoler
		AdminDomainRef domainRef = folder.getDomainRef();

		for (int i=0; i<moldNoVt.size(); i++) {
			String moldName = (String)moldNoVt.elementAt(i);
			AdminDomainRef domainRef1=null;

			try {
				domainRef1=AdministrativeDomainHelper.manager.createDomain(domainRef,moldName,moldName,containerRef);
			}

			catch (Exception ex) {
				ex.printStackTrace();
			}

			String folder2ndPath = "/Default/"+productName+"/"+moldName;
			if (VERBOSE)
				System.out.println(">>create subfolder '"+folder2ndPath+"'...");
				SubFolder subFolder = null;


				//FolderHelper.service.createSubFolder(folder2ndPath, domainRef, containerRef);
				try{//modified by Wang, Hongxing
					subFolder = (SubFolder)FolderHelper.service.createSubFolder(folder2ndPath, domainRef1, containerRef);
				}
				catch(wt.pom.UniquenessException ue){
					if (VERBOSE){
					System.out.println(">>create subfolder, "+folder2ndPath+" existed.");
				}
			}

			for (int j=0; j<subfolderVt.size(); j++) {
				String subFolderName = (String)subfolderVt.elementAt(j);
				if(VERBOSE)
					System.out.println("SUBFOlder = " + subFolderName);
				String folder3rd4stPath = folder2ndPath+"/"+subFolderName;
				String folderRealName = "";
				AdminDomainRef domainRef2=null;

				if(subFolderName.indexOf("/")<0) {
					try {
						folderRealName = subFolderName;
						if(domains.contains(subFolderName))
							domainRef2=AdministrativeDomainHelper.manager.createDomain(subFolder.getDomainRef(),subFolderName,subFolderName,containerRef);
					} catch (Exception ex) {
						//domainRef2 = AdminDomainRef.newAdminDomainRef(AdministrativeDomainHelper.manager.getDomain(subFolderName,containerRef));
						System.out.println("Create Domain Error for folder=" + subFolderName +" " + ex.getMessage());
					}
				}

				else if(subFolderName.indexOf("/")>0) {
					int index = subFolderName.indexOf("/");
					String parentFolder = subFolderName.substring(0,index);
					folderRealName = subFolderName.substring(index+1);
					AdminDomainRef ParentdomainRef = null;

					try {
						//String dPath = AdministrativeDomainHelper.manager.getDomainPath((AdministrativeDomain)domainRef1.getObject());
						ParentdomainRef = AdminDomainRef.newAdminDomainRef(AdministrativeDomainHelper.manager.getDomain("/Default/" + moldName+"/"+ parentFolder,containerRef));
					}

					catch (Exception ex) {
						ParentdomainRef = domainRef1;
					}

					try {
						if(domains.contains(folderRealName))
							domainRef2=AdministrativeDomainHelper.manager.createDomain(ParentdomainRef,folderRealName,folderRealName,containerRef);
					} catch (Exception ex) {
						System.out.println("Create Domain Error for folder " + subFolderName + " " + ex.getMessage());
					}
				}

				if (VERBOSE)
					System.out.println(">>create subfolder '"+folder3rd4stPath+"'...");

					//FolderHelper.service.createSubFolder(folder3rd4stPath, domainRef, containerRef);
					try{//modified by Wang, Hongxing
						FolderHelper.service.createSubFolder(folder3rd4stPath, domainRef2, containerRef);
					}

					catch(wt.pom.UniquenessException ue){
						if (VERBOSE){
						System.out.println(">>create subfolder, "+folder3rd4stPath+" existed.");
					}
				}

				try {
					if(domainRef2 != null) {
						Vector rules = (Vector)ht.get(folderRealName);
						if(rules == null)
							continue;
					else {
						if(VERBOSE)
						System.out.println("begint to SET PERMSSION TO FOLDER *" +subFolderName +" " + rules);

						for (int k = 0; k<rules.size(); k++) {
							String groupName = "";
							if(VERBOSE)
								System.out.println("FolderUtil:\t======Begin to add ACLRule to Folder " + subFolderName+"===");
							Hashtable rule = (Hashtable)rules.get(k);

							String type = (String)rule.get("TYPE");

						//type = "WCTYPE|" + type;
						//TypeIdentifier typeId = TypeIdentifierUtilityHelper.service.getTypeIdentifier(type);
						//TypeIdentifier typeId = TypeIdentifierUtility.getTypeIdentifierFromPersistedType(type);

						TypeIdentifier typeId = CoreMetaUtility.getTypeIdentifier(type);
						if(VERBOSE)
							System.out.println("FolderUtil:\tType is " + type +", typeId="+typeId);

						Vector permission = (Vector)rule.get("PERMISSION");
						Vector deny = (Vector)rule.get("DENYPERMISSION");

						if(VERBOSE) {
							System.out.println("FolderUtil:\tPERMISSION is \t" + permission);
							System.out.println("FolderUtil:\tDENY PERMISSION is \t" + deny);
						}

						State state = null;
						String strState = (String)rule.get("STATE");

						if(strState.equals("ALL"))
							state = null;
						else
							state = State.toState(strState);
						String rolename = groupName = (String)rule.get("GROUP");

						if(groupName == null || "".equals(groupName)) {
							groupName = moldName+" " +ht.get(subFolderName+"RoleName");

							if(groupName == null || "".equals(groupName)) {
								throw new WTException("ext.fih.pdmlink.FolderUtil:Error while Adding ACL to Folder " + subFolderName + ",GroupName and RoleName is null");
							}
							else {
								Role AccessRole = Role.toRole(groupName);
								if(VERBOSE)
									System.out.println("FolderUtil:\tadd role " + AccessRole);

								ContainerTeam team = (ContainerTeam)product.getContainerTeamReference().getObject();
								team.addPrincipal(AccessRole,null);
							}
						}

						//PersistenceHelper.manager.save(team);
						WTGroup group = getGroup(groupName);

							if(group == null)
								throw new WTException("ext.fih.pdmlink.FolderUtil:Error while Adding ACL to Folder " + subFolderName + ",Group does not exist.GroupName="+groupName);
									WTPrincipalReference ref = WTPrincipalReference.newWTPrincipalReference(group);
									DomainAdministratorHelper.service.createAccessControlRule(domainRef2,typeId,state,ref,permission,deny);

								if(VERBOSE)
									System.out.println("FolderUtil:\t======End to add ACLRule to Folder " + subFolderName+"===");
							}
						}
					}
				}

				catch (Exception ex) {
					if(VERBOSE)
						System.out.println("Add ACLRule to Domain error,FolderName=" + subFolderName + " DomainRef=" + domainRef2);
					ex.printStackTrace();
				}
			}
		}

		if (msg.equals(""))
			msg="OK";
		return msg;
	}

	/**
	* @param subfolderVt
	*/
	public static void parseProperties(Vector subfolderVt) {
		StringTokenizer stk1 = new StringTokenizer(subfolders, DELIM_3RD_FOLDER);

		while(stk1.hasMoreElements()) {
			String subfolder = (String)stk1.nextElement();
			StringTokenizer stk2 = new StringTokenizer(subfolder, DELIM_3RD_AND_4ST);
			while(stk2.hasMoreElements()) {
				String folder3rd = (String)stk2.nextElement();
				subfolderVt.addElement(folder3rd);
				String folder4st = "";

				if(stk2.hasMoreTokens()) {
					folder4st = (String)stk2.nextElement();
					StringTokenizer stk3 = new StringTokenizer(folder4st, DELIM_4ST_FOLDER);
					while(stk3.hasMoreElements()) {
						String folder = (String)stk3.nextElement();
					String folderPath = folder3rd+"/"+folder;
					subfolderVt.addElement(folderPath);
					}
				}
			}
		}
	}

	/**
	* @return
	*/
	public static Hashtable getAccessProperites() {
	Hashtable ht = new Hashtable();
	String roleName = "";
	String rules = "";
	String domains = "";
	Vector rulesVec = new Vector();

	try {
		domains = WTProperties.getLocalProperties().getProperty("ext.fih.pdmlink.SubFolderDomain","");
		int i = 1;
		while(true) {
			rules= WTProperties.getLocalProperties().getProperty("ext.fih.pdmlink.AccessRule"+(i++),"");


		if(rules != null && !"".equals(rules))
			rulesVec.add(rules);
		else
			break;
		}
	}

	catch (Exception ex) {
		if(VERBOSE)
			System.out.println("ext.fih.pdmlink.FolderUtil:\tRead Role or Access Error,message=" + ex.getMessage());
	}

	StringTokenizer stDomain = new StringTokenizer(domains,",");

	for (int i = 0; i<rulesVec.size(); i++) {

		Hashtable htrule = new Hashtable();
		String strACLRule = (String)rulesVec.get(i);
		String folderName = "";
		String type = "";
		String permission = "";
		String state = "";
		String deny = "";
		String group = "";

		int index = strACLRule.indexOf("/");
		folderName = strACLRule.substring(0,index);
		strACLRule = strACLRule.substring(index+1);

		try {
			roleName = WTProperties.getLocalProperties().getProperty("ext.fih.pdmlink."+folderName+"RoleName","");
			if(!"".equals(roleName))
				ht.put(folderName+"RoleName",new String(roleName.getBytes()));
		}

		catch(Exception e) {
		}

			index = strACLRule.indexOf("/");
			if(index >=0)
				type = strACLRule.substring(0,index);
				strACLRule = strACLRule.substring(index+1);

			index = strACLRule.indexOf("/");
			if(index >=0)
				state = strACLRule.substring(0,index).toUpperCase();
				strACLRule = strACLRule.substring(index+1);

			index = strACLRule.indexOf("/");
			if(index >=0)
				group = strACLRule.substring(0,index);
				strACLRule = strACLRule.substring(index+1);

			index = strACLRule.indexOf("/");
			if(index >=0)
				permission = strACLRule.substring(0,index).toUpperCase();
				strACLRule = strACLRule.substring(index+1);

			index = strACLRule.indexOf("/");
			if(index >=0)
				deny = strACLRule.substring(0,index).toUpperCase();
			else
				deny = strACLRule;

			htrule.put("TYPE",type);
			htrule.put("STATE",state);
			htrule.put("GROUP",group);

			try {
				htrule.put("PERMISSION",getPermissionVector(permission,true));
				htrule.put("DENYPERMISSION",getPermissionVector(deny,false));
			}

			catch (Exception ex) {
				if(VERBOSE)
					System.out.println("Get Access Rule Error " + ex.getMessage());
			}

			if(!ht.containsKey(folderName)) {
				Vector v = new Vector();
				v.add(htrule);
				ht.put(folderName,v);
			}

			else {
				Vector v = (Vector)ht.get(folderName);
				v.add(htrule);
			}
		}

		Vector domainVec = new Vector();
		while(stDomain.hasMoreElements()) {
			String domain = (String)stDomain.nextElement();
			domainVec.add(domain);
		}

		ht.put("domains",domainVec);
		return ht;
	}

	/**
	* ??????
	* @param permissionString ???
	* @param positive ??????
	* @return ??
	*/
	public static Vector getPermissionVector(String permissionString,boolean positive) throws Exception {

	Vector permissionVector = new Vector();
	Vector vtemp = new Vector();
	StringTokenizer stPermission = new StringTokenizer(permissionString,",",true);

	while(stPermission.hasMoreElements()) {
		String tempPermission = (String)stPermission.nextElement();
		tempPermission = tempPermission.trim();
		tempPermission = tempPermission.toUpperCase();

		if(!vtemp.contains(tempPermission)) {
			if(positive&&tempPermission.equals("CREATE")) {
				if(!vtemp.contains("READ")) {
					vtemp.add("READ");
					permissionVector.add(AccessPermission.READ);
				}

				if(!vtemp.contains("MODIFY")) {
					vtemp.add("MODIFY");
					permissionVector.add(AccessPermission.MODIFY);
				}
					vtemp.add("CREATE");
					permissionVector.add(AccessPermission.CREATE);
				}

				else if(tempPermission.equals("CREATE")) {
					vtemp.add("CREATE");
					permissionVector.add(AccessPermission.CREATE);
				}

				else if(tempPermission.equals("ADMINISTRATIVE")) {
					vtemp.add("ADMINISTRATIVE");
					permissionVector.add(AccessPermission.ADMINISTRATIVE);
				}

				else if(tempPermission.equals("ALL")) {
					vtemp.add("ALL");
					permissionVector.add(AccessPermission.ALL);
				}

				else if(tempPermission.equals("CHANGE_PERMISSIONS")) {
					vtemp.add("CHANGE_PERMISSIONS");
					permissionVector.add(AccessPermission.CHANGE_PERMISSIONS);
				}

				else if(tempPermission.equals("DELETE")) {
					vtemp.add("DELETE");
					permissionVector.add(AccessPermission.DELETE);
				}

				else if(tempPermission.equals("READ")) {
					vtemp.add("READ");
					permissionVector.add(AccessPermission.READ);
				}

				else if(tempPermission.equals("MODIFY")) {
					vtemp.add("MODIFY");
					permissionVector.add(AccessPermission.MODIFY);
				}

				else if(tempPermission.equals("REVISE")) {
					vtemp.add("REVISE");
					permissionVector.add(AccessPermission.REVISE);
				}

				else if(tempPermission.equals("NEW_VIEW_VERSION")) {
					vtemp.add("NEW_VIEW_VERSION");
					permissionVector.add(AccessPermission.NEW_VIEW_VERSION);
				}
			}
		}
		return permissionVector;
	}

	/**
	* @param name ??
	* @return ?
	*/
	public static WTGroup getGroup(String name) throws Exception {
		WTGroup group = null;
		QuerySpec qs = new QuerySpec(WTGroup.class);
		SearchCondition sc = new SearchCondition(WTGroup.class, WTGroup.NAME, SearchCondition.EQUAL, name);

		qs.appendSearchCondition(sc);
		QueryResult qr = PersistenceHelper.manager.find(qs);

		if(qr.hasMoreElements())
			group = (WTGroup) qr.nextElement();
		return group;
	}

	public static PDMLinkProduct getPDMLinkProductByName(String name) throws WTException {
		PDMLinkProduct product = null;

		QuerySpec qs = new QuerySpec(PDMLinkProduct.class);
		SearchCondition sc = new SearchCondition(PDMLinkProduct.class, PDMLinkProduct.NAME, SearchCondition.EQUAL, name);

		qs.appendSearchCondition(sc);
		QueryResult qr = PersistenceHelper.manager.find(qs);

		if(qr.hasMoreElements())
			product = (PDMLinkProduct) qr.nextElement();
		return product;
	}

	public static void main(String args[]) throws Exception {
		if(args.length <=0) {
			System.out.println("Usage:\twindchill ext.fih.pdmlink.FolderUtil ProductName MoldNumber");
			System.out.println("Example:\twindchill ext.fih.pdmlink.FolderUtil TestAccess CA0611");
		}

		else {
			System.out.println(TypedUtility.getExternalTypeIdentifier("wt.doc.WTDocument|com.foxera.Agenda"));

			//TypeIdentifier typeId = TypeIdentifierUtilityHelper.service.getTypeIdentifier("wt.doc.WTDocument");
			//TypeAdminServiceIfcFwd a = new TypeAdminServiceIfcFwd();
			//System.out.println (TypeIdentifierUtility.getTypeIdentifier("WCTYPE|wt.doc.WTDocument|com.foxera.Agenda"));

			System.out.println(TypeIdentifierUtility.getTypeIdentifier("wt.doc.WTDocument"));
			System.out.println(TypeIdentifierUtility.getInstance().getTypeIdentifier("com.foxera.Agenda"));

			// System.out.println (typeId);
			/*FolderUtil.VERBOSE = true;
			System.out.println("=====begin===");
			System.out.println("VERBOSE = " + VERBOSE);
			System.out.println (getAccessProperites());
			Vector v = new Vector();
			v.add(args[1] + "0");
			v.add(args[1] + "1");
			createFolders(args[0],args[0],v); */
		}
	}
}