package com.eactive.eai.transformer.message;
//package com.eactive.eai.transformer.message;
//
//import java.util.Hashtable;
//import java.util.Iterator;
//import java.util.Map;
//import java.util.Stack;
//import java.util.regex.Matcher;
//import java.util.regex.Pattern;
//
//import weblogic.wtc.jatmi.FML;
//import weblogic.wtc.jatmi.Ferror;
//import weblogic.wtc.jatmi.FldTbl;
//import weblogic.wtc.jatmi.FmlKey;
//import weblogic.wtc.jatmi.TypedFML;
//import weblogic.wtc.jatmi.TypedFML32;
//
//import com.eactive.eai.adapter.wtc.CrmFmlTable;
//import com.eactive.eai.transformer.layout.Item;
//import com.eactive.eai.transformer.layout.Types;
//import com.eactive.eai.transformer.message.data.MessageData;
//import com.eactive.eai.transformer.util.Constants;
//
// 
///**
// *
// *  [ FMLMessagae 정의 ]
// *        1. 단일 필드 : FILED
// *        2. 배열 필드 : FIELD[9]
// *        3. 단일 그룹 내 배열 필드 지원 안함 (GROUP.FIELD[3])
// *        4. 배열 그룹 내 단일 필드 : GROUP[3].FIELD
// *        5. 변환 시 GROUP 매핑 지원을 위해 GROUP 필드 지원
// *        6. MESSAGE 필드 지원 안함.
// *        7. GROUP의 GROUP은 지원 안함.
// *        8. GROUP:*, FIELD:* 지원함
// */
//public class FMLMessage extends Message {
//    public static final String NAME = "FML";
//    public static final String MESSAGE_FML = "FML";
//    public static final String MESSAGE_FML32 = "FML32";
//    private FML data;
//    
//    private static final Hashtable FchgErrors = new Hashtable();
//
//    public FMLMessage() {
//        super();
//        
//        FchgErrors.put("1 (FALIGNERR)",       "필드 버퍼 정렬 오류");
//        FchgErrors.put("2 (FNOTFLD)",         "필드 버퍼 오류");   
//        FchgErrors.put("3 (FNOSPACE)",        "필드버퍼 공간 부족 오류");   
//        FchgErrors.put("4 (FNOTPRES)",        "필드 존재 오류");   
//        FchgErrors.put("5 (FBADFLD)",         "잘못된 필드 넘버 또는 유형 오류");
//        FchgErrors.put("6 (FTYPERR)",         "잘못된 필드 유형 오류");
//        FchgErrors.put("7 (FEUNIX)",          "UNIX 시스템 콜 오류"); 
//        FchgErrors.put("8 (FBADNAME)",        "잘못된 필드명 오류");  
//        FchgErrors.put("9 (FMALLOC)",         "메모리 할당 오류"); 
//        FchgErrors.put("10 (FSYNTAX)",        "잘못된 문법 오류");   
//        FchgErrors.put("11 (FFTOPEN)",        "필드 테이블 찾기 또는 열기 오류");
//        FchgErrors.put("12 (FFTSYNTAX)",      "");
//        FchgErrors.put("13 (FEINVAL)",        "잘못된 인자 오류");
//        FchgErrors.put("14 (FBADTBL)",        "필드 테이블 동시 접근 오류");
//        FchgErrors.put("15 (FBADVIEW)",       "뷰 찾기 또는 얻기 오류");
//        FchgErrors.put("16 (FVFSYNTAX)",      "뷰 파일 문법 오류");
//        FchgErrors.put("17 (FVFOPEN)",        "뷰 파일 찾기 또는 열기 오류");
//        FchgErrors.put("18 (FBADACM)",        "ACM이 음수 포함 오류");
//        FchgErrors.put("19 (FNOCNAME)",       "Cname 찾기 오류");
//    }
//
//    // Getter/Setter -------------------------------------------------------------------
//    public Object getData() {
//        return this.data;
//    }
//
//    protected void doSetData(Object data) {
//        if (!(data instanceof FML)) {
//            throw new InvalidDataTypeException("not instance of FML class.", data);
//        }
//
//        String name = this.layout.getLayoutType().getName();
//        String fullName = null;
//        String fname = null;
//        try {
//            Iterator fmliter = ((FML) data).Fiterator();
//
//            while (fmliter.hasNext()) {
//                Map.Entry entry = (Map.Entry) fmliter.next();
//                FmlKey fmlkey = (FmlKey) entry.getKey();
//                
//                try {
//                    fname = this.data.Fname(fmlkey.get_fldid());
//                } 
//                catch (Exception tpe) {
//                    //logger.warn(getName() + " (FMLMessage) | skip Undefined fldid [" + fmlkey.get_fldid() + "]");
//                    //MemoryLogger.error("<WARN> " + getName() + " (FMLMessage) | skip Undefined fldid [" + fmlkey.get_fldid() + "]");
//                    continue;                   
//                }
//                Item item = findItemByPath(fname);
//                
//                if(item == null) {
//                    //logger.warn(getName() + " (FMLMessage) | skip Undefined Item - (item path) fname[" + fname + "]");
//                    //MemoryLogger.error("<WARN> " + getName() + " (FMLMessage) | skip Undefined Item - (item path) fname[" + fname + "]");
//                    continue;
//                }
//                else {
//                    fullName = item.getItemPath();
//                }
//                
//                /**
//                 * group 에 occurrence 두는 것은 없앤다.
//                 */
//                if (item.getParent().isGroup() && item.getParent().getOccMax() != 1) {
//                    fullName = item.getParent().getParent().getItemPath() + Types.FIELD_SEPARATOR + 
//                    		   item.getParent().getName() + "[" + fmlkey.get_occurance() + "]" + Types.FIELD_SEPARATOR + 
//                               item.getName() + "[0]";
//                } else {
//                    fullName = item.getParent().getItemPath() + Types.FIELD_SEPARATOR +
//                               item.getName() + "[" + fmlkey.get_occurance() + "]";
//                }
//
//                item = getOrCreateItem(fullName, true);
//
//                if (item == null) {
//                    continue;
//                }
//                
//                switch (this.data.Fldtype(fmlkey.get_fldid())) {
//                    /*
//                    case FML.FLD_DOUBLE :
//                        item.setValue((Double)entry.getValue());
//                        break;         
//                    case FML.FLD_STRING :
//                        item.setValue((String)entry.getValue());
//                        break;         
//                    case FML.FLD_LONG :
//                        item.setValue((Long)entry.getValue());
//                        break;         
//                    case FML.FLD_FLOAT :
//                        item.setValue((Float)entry.getValue());
//                        break;         
//                    case FML.FLD_INT :
//                        item.setValue((Integer)entry.getValue());
//                        break;
//                    */
//                    default:               	
//                        item.setValue(entry.getValue());
//                        break;
//                }
//            }
//        } catch (weblogic.wtc.jatmi.Ferror e) {
//        	StringBuffer sb = new StringBuffer();
//        	sb.append("전문레이아웃 매핑 중 데이터 오류 (" + e.getMessage() + ")");
//        	sb.append("\n");
//        	sb.append("전문레이아웃="+getName());
//            throw new MessageException(sb.toString(), e);
//        } catch (Exception e) {
//        	StringBuffer sb = new StringBuffer();
//        	sb.append("전문레이아웃 매핑 중 데이터 오류 (" + e.getMessage() + ")");
//        	sb.append("\n");
//        	sb.append("전문레이아웃="+getName());
//            throw new MessageException(sb.toString(), e);
//        }
//
//        try {
//            if (MESSAGE_FML.equals(name) || MESSAGE_FML32.equals(name)) {
//                this.data = (FML) data;
//            } else {
//            	StringBuffer sb = new StringBuffer();
//            	sb.append("전문레이아웃 매핑 중 데이터 오류 (전문레이아웃에 설정하려는 데이터가 FML,FML32 타입이 아닙니다.)");
//            	sb.append("\n");
//            	sb.append("전문레이아웃="+getName());
//                
//            	throw new InvalidDataTypeException(sb.toString(), data);
//            }
//        } catch (Exception e) {
//        	StringBuffer sb = new StringBuffer();
//        	sb.append("전문레이아웃 매핑 중 데이터 오류 (" + e.getMessage() + ")");
//        	sb.append("\n");
//        	sb.append("전문레이아웃="+getName());
//            throw new InvalidDataTypeException(sb.toString(), data, e);
//        }
//    }
//
//    public void createObject() {
//        Item root = layout.getRootItem();
//        String className = root.getRefInfo();
//        String name = this.layout.getLayoutType().getName();
//
//        FldTbl tbl = null;
//
//        try {
//        	if (className == null || "".equals(className))
//        		className = "com.eactive.eai.adapter.wtc.CrmFmlTable";
//            Class c = Class.forName(className);
//            tbl = (FldTbl) c.newInstance();
//        } catch (ClassNotFoundException e) {
//        	StringBuffer sb = new StringBuffer();
//        	sb.append("전문레이아웃 매핑 중 데이터 오류 FML 클래스를 못찾음  ( " + className + ")");
//        	sb.append("\n");
//        	sb.append("전문레이아웃="+getName());
//            throw new MessageException(sb.toString(), e);
//        } catch (Exception e) {
//        	StringBuffer sb = new StringBuffer();
//        	sb.append("전문레이아웃 매핑 중 데이터 오류 (" + e.getMessage() + ")");
//        	sb.append("\n");
//        	sb.append("전문레이아웃="+getName());
//        	throw new MessageException(sb.toString(), e);
//        }
//
//        if (MESSAGE_FML.equals(name)) {
//            this.data = new TypedFML((FldTbl) tbl);
//        } else if (MESSAGE_FML32.equals(name)) {
//            this.data = new TypedFML32((FldTbl) tbl);
//        } else {
//        	StringBuffer sb = new StringBuffer();
//        	sb.append("전문레이아웃 매핑 중 데이터 오류 (전문레이아웃에 설정하려는 데이터가 FML,FML32 타입이 아닙니다.)");
//        	sb.append("\n");
//        	sb.append("전문레이아웃="+getName());
//            throw new RuntimeException(sb.toString());
//        }
//    }
//
//    public int occurrence(Item item) {
//        String path = item.getPath();
//
//        int id = -1;
//
//        try {
//            id = this.data.Fldid(path);
//        } catch (Exception e) {
//            return -1;
//        }
//
//        try {
//            return this.data.Foccur(id);
//        } catch (Exception e) {
//            return -1;
//        }
//    }
//
//    protected void composeData(Item item, Object value) {
//        //if(logger.isInfoEnabled()) logger.info("[FMLMessage] composeData(" + item.getItemPath() + ", " + value + ")");
//        
//        if (item.getIndex() < 0)
//            return;
//        
//        String itemPath = item.getItemPath();
//
//        if (!item.isField()) {
//            return;
//        }
//
//        //FML일 경우는 group과 field의 occurrence를 바꾼다.
//        int occurrence = 0;
//        
//        // Group 이 반복이 없는 경우 이상현상 방지 : 2009.09.03
//        if (item.getParent().isGroup()) {
//        	if(item.getParent().getIndex() > -1) {
//        		occurrence = item.getParent().getIndex();
//        	}
//        	else {
//        		occurrence = item.getIndex();
//        	}
//        } else {
//            occurrence = item.getIndex();
//        }
//
//        int id = -1;
//
//        try {
//	     	Matcher m = Pattern.compile("([a-zA-Z0-9_]+)\\[([0-9]+)\\]").matcher(item.getPath());
//	        if (m.find()) {
//        		id = this.data.Fldid(m.group(1));
//        		occurrence = Integer.parseInt(m.group(2));
//        	} else {
//        		id = this.data.Fldid(item.getPath());
//        	}
//        } catch (Exception e) {
//            throw new InvalidAccessException(
//                "FML 필드를 찾을 수 없음 [path=" + item.getPath() + "] - " + e.getMessage(),
//                itemPath,
//                item.getRoot(),
//                e);
//        }
//        
//        try {
//        	switch (this.data.Fldtype(id)) {
//        	case FML.FLD_DOUBLE :
//        		if (item.getValue() instanceof Number) {
//        			this.data.Fchg(id, occurrence, ((Number) item.getValue()).doubleValue());
//        		} else if (item.getValue() instanceof String) {
//        			if ("".equals(((String) item.getValue()).trim()))
//            			this.data.Fchg(id, occurrence, 0.0);
//        			else 
//        				this.data.Fchg(id, occurrence, Double.parseDouble((String) item.getValue()));
//            	} else {
//        			this.data.Fchg(id, occurrence, item.getValue());
//        		}
//        		break;
//        	case FML.FLD_LONG :
//        		if (item.getValue() instanceof Number) {
//        			this.data.Fchg(id, occurrence, ((Integer) item.getValue()).intValue());
//        		} else if (item.getValue() instanceof String) {
//        			if ("".equals(((String) item.getValue()).trim()))
//            			this.data.Fchg(id, occurrence, 0);
//        			else 
//        				this.data.Fchg(id, occurrence, Long.parseLong((String) item.getValue()));
//            	} else {
//        			this.data.Fchg(id, occurrence, item.getValue());
//        		}
//        		break;
//        	default :
//        		this.data.Fchg(id, occurrence, item.getValue());
//        		break;
//        	}
//        } catch(Ferror e) {
//            throw new MessageException( 
//            		itemPath + " (" + item.getPath() + ") 에 값 (" + item.getValue() + ")을 설정할 수 없음 - " +
//            		e.getMessage() + 
//            		(FchgErrors.get(e.getMessage()) == null ? "" : " - " + FchgErrors.get(e.getMessage())) +
//            		"\n" + item.getRoot(),
//            		e);
//        } catch (Exception e) {            
//            throw new InvalidAccessException(
//            		itemPath + " (" + item.getPath() + ") 에 값 (" + item.getValue() + ")을 설정할 수 없음 - " +
//            		e.getMessage() + " - " + ((Item) this).getRefInfo(), 
//                itemPath, 
//                (Message) item.getRoot(),
//                e);
//        }
//    }
//
//    
//    /**
//     * 그룹 변환에서 사용되는 API.
//     */
//    public MessageData getMessageData(String itemPath) {
//        return null;
//    }
//
//    /**
//     * 그룹 변환에서 사용되는 API.
//     */
//    public void setMessageData(String itemPath, MessageData messageData) {
//    }
//
//    public void copy(Message message) {
//        if (!(message instanceof FMLMessage)) {
//            throw new InvalidMessageException("FMLMessage] Invlid Message for copy.",
//                message);
//        }
//
//        Object obj = null;
//
//        try {
//            obj = message.getData();
//        } catch (InvalidDataTypeException e) {
//            throw new InvalidMessageException(e, message);
//        }
//
//        if (!(obj instanceof FML)) {
//            throw new InvalidMessageException("FMLMessage] Invlid FMLMessage",
//                message);
//        }
//
//        FML fml = (FML) obj;
//
//        try {
//            String[] names = fml.getFieldTables()[0].getFldNames();
//
//            for (int i = 0; i < names.length; i++) {
//                int id = fml.Fldid(names[i]);
//
//                for (int j = 0; j < fml.Foccur(id); j++) {
//                    this.data.Fchg(id, j, fml.Fget(id, j));
//                }
//            }
//        } catch (Exception e) {
//            throw new InvalidMessageException(
//                "FMLMessage] Cannot copy the object. - " + e.getMessage(),
//                message);
//        }
//    }
//	
//    public String toLogString() {
//		StringBuffer sb = new StringBuffer();
//		Stack stack = new Stack();
//		sb.append(getName() + "[");
//		stack.push("]");
//
//		int prevDepth = 1;
//		for (Iterator iter = iterator(); iter.hasNext();) {
//			Item item = (Item) iter.next();
//
//			/**
//			 * index == -1 인 경우는 무시한다
//			 */
//			if (item.getIndex() < 0) {
//				continue;
//			}
//			
//			/**
//			 * depth 가 낮아질 때(tree를 빠져 나올 때), ']' 를 찍어준다.
//			 */
//			if (item.getDepth() < prevDepth) {
//				sb.append(stack.pop());
//			}
//			
//			/**
//			 * ','로 구성요소를 구분해 준다.
//			 */
//			if (item.getDepth() <= prevDepth) {
//				sb.append(", ");
//			}
//
//	        switch (item.getNodeTypeId()) {
//			case NODE_FIELD:
//	            if ("Y".equals(item.getMask()))
//	                sb.append(item.getName() + "=" + item.maskString(item.getValue()));
//	            else
//	                sb.append(item.getName() + "=" + item.getValue());
//	            break;
//			case NODE_GROUP:
//			case NODE_MESSAGE:				
//				sb.append(item.getName() + "[");
//				stack.push("]");
//				break;
//	        }
//	        
//	        /**
//	         * 이전 depth를 저장해 둔다.
//	         */
//			prevDepth = item.getDepth();
//		}
//		
//		/**
//		 * 필요한 만큼 ']'를 찍어준다.
//		 */
//		while(stack.size() > 0) {
//			sb.append(stack.pop());
//		}
//		
//        return sb.toString();
//    }
//
//    
//    public String toString() {
//        // if staled -> reorganize data
//        try {
//            getData();
//        } catch (Exception e) {
//            logger.error("[FMLMessage] " + e.getMessage(), e);
//        }
//
//        StringBuffer sb = new StringBuffer();
//        sb.append(getName() + " (FMLMessage)");
//        sb.append(super.toString());
//        
//        FldTbl[] ft = data.getFieldTables();
//        
//        //----------------------------------------------------------------------
//        // JMS Queue 또는 Remote로 전달할 경우 FieldTable은 전송되지 않는다.
//        // 이에 대한 처리방안
//        //----------------------------------------------------------------------
//        if(ft == null) {
//            FldTbl[] pft = {new CrmFmlTable()};
//            data.setFieldTables(pft);
//        }        
//        
//        if (data != null) {
//            sb.append("\n" + Constants.TAB + " | data = " + data);    
//            try {
//                Iterator fmliter = data.Fiterator();
//    
//                while (fmliter.hasNext()) {
//                    Map.Entry entry = (Map.Entry) fmliter.next();
//                    FmlKey fmlkey = (FmlKey) entry.getKey();
//    
//                    switch (data.Fldtype(fmlkey.get_fldid())) {
//                        default:
//                            sb.append(String.format("\n" + Constants.TAB + " | %15s[%3d] : %3s : %s", 
//                            		data.Fname(fmlkey.get_fldid()),
//                            		fmlkey.get_occurance(),
//                            		data.Fldtype(fmlkey.get_fldid()),
//                            		entry.getValue()
//                            		));
//                            break;
//                    }
//                }
//            } catch (weblogic.wtc.jatmi.Ferror e) {
//                sb.append(String.format("\n" + Constants.TAB + " | %15s", 
//                		"[WARN] - fml read error - " + e.getMessage()));
//            }
//        }
//        sb.append("\n" + Constants.TAB + " +--------------------------------------------------------------------------------------------------+");
//
//        return sb.toString();
//    }
//}
