/** * Copyright (C) 2014 KAIST * @author Janggwan Im <limg00n@kaist.ac.kr> */ package org.fosstrak.ale.server.tm; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.fosstrak.ale.exception.ECSpecValidationException; import org.fosstrak.ale.exception.ImplementationException; import org.fosstrak.ale.server.Pattern; import org.fosstrak.ale.server.PatternUsage; import org.fosstrak.ale.wsdl.aletm.epcglobal.DuplicateNameExceptionResponse; import org.fosstrak.ale.wsdl.aletm.epcglobal.ImplementationExceptionResponse; import org.fosstrak.ale.wsdl.aletm.epcglobal.NoSuchNameExceptionResponse; import org.fosstrak.ale.wsdl.aletm.epcglobal.TMSpecValidationExceptionResponse; import org.fosstrak.ale.xsd.ale.epcglobal.TMFixedFieldListSpec; import org.fosstrak.ale.xsd.ale.epcglobal.TMFixedFieldSpec; import org.fosstrak.ale.xsd.ale.epcglobal.TMSpec; import org.fosstrak.ale.xsd.ale.epcglobal.TMVariableFieldListSpec; public class SymbolicFieldRepo { /** * Data structure to store symbolic field information for TMSpec API. * * It consists of a map of epcPattern to symbolic field map, which is a map of fieldname to symbolic field */ private static SymbolicFieldRepo repo = null; //private Map<String, Map<String, SymbolicField>> mapEPCPatternAndSymbolicFieldMap = new HashMap<String, Map<String, SymbolicField>>(); private Map<String, SymbolicField> mapFieldnameAndSymbolicField = new HashMap<String, SymbolicField>(); private Map<String, TMSpec> mapEPCPatternAndTMSpec = new HashMap<String, TMSpec>(); //private Map<String, Pattern> mapEPCPatternAndPatternObject = new HashMap<String, Pattern>(); public SymbolicFieldRepo() { } public void addSymbolicField(String epcPattern, TMSpec spec) throws TMSpecValidationExceptionResponse, ImplementationExceptionResponse, DuplicateNameExceptionResponse { if(mapEPCPatternAndTMSpec.containsKey(epcPattern)) { throw new DuplicateNameExceptionResponse("TMSpec "+epcPattern+" already exists"); } // map (String fieldname, SymbolicField symbolicField) if(spec instanceof TMFixedFieldListSpec) { List<TMFixedFieldSpec> listFixedfield = ((TMFixedFieldListSpec)spec).getFixedFields().getFixedField(); for(TMFixedFieldSpec fixedfieldSpec : listFixedfield) { // validate the fieldspec if(mapFieldnameAndSymbolicField.containsKey(fixedfieldSpec.getFieldname())) { throw new TMSpecValidationExceptionResponse("fieldname "+fixedfieldSpec.getFieldname()+" already exists"); } if(fixedfieldSpec.getBank() < 0 || fixedfieldSpec.getBank() >= 4) { throw new TMSpecValidationExceptionResponse("Bank number of field "+fixedfieldSpec.getFieldname()+" is not valid"); } if(fixedfieldSpec.getLength() < 0) { throw new TMSpecValidationExceptionResponse("Length of field "+fixedfieldSpec.getFieldname()+" is not valid"); } if(fixedfieldSpec.getOffset() < 0) { throw new TMSpecValidationExceptionResponse("Offset of field "+fixedfieldSpec.getFieldname()+" is not valid"); } if(fixedfieldSpec.getFieldname().equals("epc") || fixedfieldSpec.getFieldname().equals("killPwd") || fixedfieldSpec.getFieldname().equals("accessPwd") || fixedfieldSpec.getFieldname().equals("epcBank") || fixedfieldSpec.getFieldname().equals("tidBank") || fixedfieldSpec.getFieldname().equals("userBank") || fixedfieldSpec.getFieldname().equals("afi") || fixedfieldSpec.getFieldname().equals("nsi") ) { throw new TMSpecValidationExceptionResponse("fieldname "+fixedfieldSpec.getFieldname()+" is built-in fieldname, not allowed to redefine"); } SymbolicField field = new SymbolicField(); field.setFieldType(0); // indicating "FIXED_FIELD" if(fixedfieldSpec.getFieldname().equalsIgnoreCase("epc")) { field.setDataType("epc"); field.setFormat("epc-tag"); } else if(fixedfieldSpec.getFieldname().equalsIgnoreCase("killPwd")) { // same as "@0.32" field.setBank(0); field.setLength(32); field.setOffset(0); field.setDataType("uint"); field.setFormat("hex"); } else if(fixedfieldSpec.getFieldname().equalsIgnoreCase("accessPwd")) { // same as "@0.32.32" field.setBank(0); field.setLength(32); field.setOffset(32); field.setDataType("uint"); field.setFormat("hex"); } else if(fixedfieldSpec.getFieldname().equalsIgnoreCase("epcBank")) { field.setBank(1); field.setLength(-1); // entire bank contents field.setOffset(0); field.setDataType("bits"); field.setFormat("hex"); } else if(fixedfieldSpec.getFieldname().equalsIgnoreCase("tidBank")) { field.setBank(2); field.setLength(-1); // entire bank contents field.setOffset(0); field.setDataType("bits"); field.setFormat("hex"); } else if(fixedfieldSpec.getFieldname().equalsIgnoreCase("userBank")) { field.setBank(3); field.setLength(-1); // entire bank contents field.setOffset(0); field.setDataType("bits"); field.setFormat("hex"); } else if(fixedfieldSpec.getFieldname().equalsIgnoreCase("afi")) { // same as "@1.8.24" field.setBank(1); field.setLength(8); field.setOffset(24); field.setDataType("uint"); field.setFormat("hex"); } else if(fixedfieldSpec.getFieldname().equalsIgnoreCase("nsi")) { // same as "@1.9.23" field.setBank(1); field.setLength(9); field.setOffset(23); field.setDataType("uint"); field.setFormat("hex"); } else if (fixedfieldSpec.getFieldname().startsWith("@")) { // fieldname with starts with "@" try { String[] part = fixedfieldSpec.getFieldname().substring(1).split("\\."); field.setBank(Integer.parseInt(part[0])); field.setLength(Integer.parseInt(part[1])); field.setOffset(Integer.parseInt(part[2])); field.setDataType("uint"); field.setFormat("hex"); } catch(NumberFormatException e) { throw new TMSpecValidationExceptionResponse("fieldname "+fixedfieldSpec.getFieldname()+" is wrong"); } } else { // user-defined symbolic field name field.setBank(fixedfieldSpec.getBank()); field.setLength(fixedfieldSpec.getLength()); field.setOffset(fixedfieldSpec.getOffset()); } if(fixedfieldSpec.getDefaultDatatype() != null) field.setDataType(fixedfieldSpec.getDefaultDatatype()); if(fixedfieldSpec.getDefaultFormat() != null) field.setFormat(fixedfieldSpec.getDefaultFormat()); mapFieldnameAndSymbolicField.put(fixedfieldSpec.getFieldname(), field); } } else if (spec instanceof TMVariableFieldListSpec) { throw new ImplementationExceptionResponse("not implemented yet"); } else { throw new TMSpecValidationExceptionResponse(); } synchronized(SymbolicFieldRepo.class) { mapEPCPatternAndTMSpec.put(epcPattern, spec); //mapEPCPatternAndSymbolicFieldMap.put(epcPattern, mapFieldnameAndSymbolicField); /* try { mapEPCPatternAndPatternObject.put(epcPattern, new Pattern(epcPattern, PatternUsage.FILTER)); } catch (ECSpecValidationException e) { e.printStackTrace(); throw new ImplementationExceptionResponse(e.getMessage()); }*/ } } public void removeSymbolicField(String epcPattern) throws NoSuchNameExceptionResponse { synchronized(SymbolicFieldRepo.class) { if (!mapEPCPatternAndTMSpec.containsKey(epcPattern)) { throw new NoSuchNameExceptionResponse("TMSpec name "+epcPattern+" does not exist"); } TMSpec tmspec = mapEPCPatternAndTMSpec.remove(epcPattern); if(tmspec instanceof TMFixedFieldListSpec) { TMFixedFieldListSpec spec = (TMFixedFieldListSpec)tmspec; for(TMFixedFieldSpec f : spec.getFixedFields().getFixedField()) { mapFieldnameAndSymbolicField.remove(f.getFieldname()); } } //mapEPCPatternAndSymbolicFieldMap.remove(epcPattern); //mapEPCPatternAndPatternObject.remove(epcPattern); } } public Set<String> getSymbolicFieldNames() { return mapEPCPatternAndTMSpec.keySet(); } public TMSpec getTMSpec(String epcPattern) throws NoSuchNameExceptionResponse { if(!mapEPCPatternAndTMSpec.containsKey(epcPattern)) { throw new NoSuchNameExceptionResponse("TMSpec name "+epcPattern+" does not exist"); } return mapEPCPatternAndTMSpec.get(epcPattern); } public SymbolicField getSymbolicField(String fieldname) { return mapFieldnameAndSymbolicField.get(fieldname); } public static SymbolicFieldRepo getInstance() { if(repo == null) { synchronized(SymbolicFieldRepo.class) { repo = new SymbolicFieldRepo(); } } return repo; } /* public synchronized Map<String, SymbolicField> findSymbolicFieldMap(String epc) { for(String key : mapEPCPatternAndSymbolicFieldMap.keySet()) { System.out.println(key); Pattern p = mapEPCPatternAndPatternObject.get(key); try { if(p.isMember(epc)) { return mapEPCPatternAndSymbolicFieldMap.get(key); } } catch (ECSpecValidationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ImplementationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; }*/ }