Java tutorial
/** * personium.io * Copyright 2014 FUJITSU LIMITED * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.personium.core.bar; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; import javax.ws.rs.ext.RuntimeDelegate; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; import org.apache.commons.io.IOUtils; import org.apache.commons.io.input.CloseShieldInputStream; import org.apache.wink.webdav.WebDAVMethod; import org.apache.wink.webdav.model.Getcontenttype; import org.apache.wink.webdav.model.Multistatus; import org.apache.wink.webdav.model.Prop; import org.apache.wink.webdav.model.Propertyupdate; import org.apache.wink.webdav.model.Propstat; import org.apache.wink.webdav.model.Resourcetype; import org.apache.wink.webdav.model.Response; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.JsonToken; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.exc.UnrecognizedPropertyException; import org.json.simple.JSONObject; import org.odata4j.core.OEntity; import org.odata4j.core.OEntityId; import org.odata4j.core.OEntityIds; import org.odata4j.core.OEntityKey; import org.odata4j.edm.EdmAssociation; import org.odata4j.edm.EdmAssociationEnd; import org.odata4j.edm.EdmComplexType; import org.odata4j.edm.EdmDataServices; import org.odata4j.edm.EdmEntityType; import org.odata4j.edm.EdmProperty; import org.odata4j.edm.EdmProperty.CollectionKind; import org.odata4j.edm.EdmStructuralType; import org.odata4j.producer.EntityResponse; import org.odata4j.stax2.XMLEventReader2; import org.odata4j.stax2.XMLFactoryProvider2; import org.odata4j.stax2.XMLInputFactory2; import org.odata4j.stax2.staximpl.StaxXMLFactoryProvider2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Element; import io.personium.common.es.util.PersoniumUUID; import io.personium.common.utils.PersoniumCoreUtils; import io.personium.core.PersoniumCoreException; import io.personium.core.PersoniumCoreMessageUtils; import io.personium.core.PersoniumUnitConfig; import io.personium.core.bar.jackson.JSONExtRoles; import io.personium.core.bar.jackson.JSONLinks; import io.personium.core.bar.jackson.JSONManifest; import io.personium.core.bar.jackson.JSONMappedObject; import io.personium.core.bar.jackson.JSONRelations; import io.personium.core.bar.jackson.JSONRoles; import io.personium.core.bar.jackson.JSONUserDataLinks; import io.personium.core.eventbus.JSONEvent; import io.personium.core.eventbus.PersoniumEventBus; import io.personium.core.model.Box; import io.personium.core.model.BoxCmp; import io.personium.core.model.Cell; import io.personium.core.model.DavCmp; import io.personium.core.model.DavCommon; import io.personium.core.model.ModelFactory; import io.personium.core.model.ctl.AssociationEnd; import io.personium.core.model.ctl.ComplexType; import io.personium.core.model.ctl.ComplexTypeProperty; import io.personium.core.model.ctl.CtlSchema; import io.personium.core.model.ctl.EntityType; import io.personium.core.model.ctl.Event; import io.personium.core.model.ctl.Event.LEVEL; import io.personium.core.model.ctl.ExtRole; import io.personium.core.model.ctl.Property; import io.personium.core.model.ctl.Relation; import io.personium.core.model.ctl.Role; import io.personium.core.model.impl.es.doc.EntitySetDocHandler; import io.personium.core.model.impl.es.odata.UserDataODataProducer; import io.personium.core.model.impl.es.odata.UserSchemaODataProducer; import io.personium.core.model.progress.Progress; import io.personium.core.model.progress.ProgressInfo; import io.personium.core.model.progress.ProgressManager; import io.personium.core.odata.OEntityWrapper; import io.personium.core.odata.PersoniumEdmxFormatParser; import io.personium.core.odata.PersoniumODataProducer; import io.personium.core.rs.cell.EventResource; import io.personium.core.rs.odata.BulkRequest; import io.personium.core.rs.odata.ODataEntitiesResource; import io.personium.core.rs.odata.ODataEntityResource; import io.personium.core.rs.odata.ODataResource; /** * Http?bar????. */ public class BarFileReadRunner implements Runnable { private static final String CODE_BAR_INSTALL_FAILED = "PL-BI-0001"; private static final String CODE_BAR_INSTALL_COMPLETED = "PL-BI-0000"; private static final String CODE_BAR_INSTALL_STARTED = "PL-BI-1001"; /** * . */ static Logger log = LoggerFactory.getLogger(BarFileReadRunner.class); static final long MB = 1024 * 1024; private static final int TYPE_WEBDAV_COLLECTION = 0; private static final int TYPE_ODATA_COLLECTION = 1; private static final int TYPE_SERVICE_COLLECTION = 2; private static final int TYPE_DAV_FILE = 3; private static final int TYPE_SVC_FILE = 4; private static final int TYPE_MISMATCH = -1; private Map<String, Boolean> barFileOrder; private File barFile; private ZipArchiveInputStream zipArchiveInputStream; private final String boxName; private final ODataEntityResource odataEntityResource; private final PersoniumODataProducer odataProducer; private final String entitySetName; private final UriInfo uriInfo; private final String requestKey; static final String ROOT_DIR = "bar/"; static final String META_DIR = "bar/00_meta/"; static final String CONTENTS_DIR_NAME = "90_contents"; static final String CONTENTS_DIR = ROOT_DIR + CONTENTS_DIR_NAME + "/"; static final String MANIFEST_JSON = "00_manifest.json"; static final String RELATION_JSON = "10_relations.json"; static final String ROLE_JSON = "20_roles.json"; static final String EXTROLE_JSON = "30_extroles.json"; static final String LINKS_JSON = "70_$links.json"; static final String ROOTPROPS_XML = "90_rootprops.xml"; static final String METADATA_XML = "00_$metadata.xml"; static final String USERDATA_LINKS_JSON = "10_odatarelations.json"; static final String USERDATA_DIR_NAME = "90_data"; private static final String DCBOX_NO_SLUSH = "dcbox:"; private static final String DCBOX = "dcbox:/"; private Cell cell; private Box box; private String schemaUrl; // ACL???? private BoxCmp boxCmp; private Map<String, DavCmp> davCmpMap; private Map<String, String> davFileMap = new HashMap<String, String>(); private long linksOutputStreamSize = Long .parseLong(PersoniumUnitConfig.get(PersoniumUnitConfig.BAR.BAR_USERDATA_LINKS_OUTPUT_STREAM_SIZE)); private long bulkSize = Long.parseLong(PersoniumUnitConfig.get(PersoniumUnitConfig.BAR.BAR_USERDATA_BULK_SIZE)); private Event event; private PersoniumEventBus eventBus; private BarInstallProgressInfo progressInfo; /** * . * @param barFile bar file object * @param cell Install target Cell * @param boxName Install target Box Name * @param odataEntityResource JAX-RS resource * @param producer ODataProducer * @param entitySetName entitySetName(=box name) * @param uriInfo uriInfo * @param requestKey ??RequestKey? */ public BarFileReadRunner(File barFile, Cell cell, String boxName, ODataEntityResource odataEntityResource, PersoniumODataProducer producer, String entitySetName, UriInfo uriInfo, String requestKey) { this.barFile = barFile; this.boxName = boxName; this.odataEntityResource = odataEntityResource; this.odataProducer = producer; this.entitySetName = entitySetName; this.uriInfo = uriInfo; this.cell = cell; this.box = null; this.boxCmp = null; this.davCmpMap = new HashMap<String, DavCmp>(); this.requestKey = requestKey; setupBarFileOrder(); } /** * bar???. */ public void run() { boolean isSuccess = true; String path = "/" + this.cell.getName() + "/" + boxName + "/"; log.debug("install target: " + path); try { List<String> doneKeys = new ArrayList<String>(); try { this.zipArchiveInputStream = new ZipArchiveInputStream(new FileInputStream(barFile)); } catch (IOException e) { throw PersoniumCoreException.Server.FILE_SYSTEM_ERROR.params(e.getMessage()); } // ("bar/")?? if (!isRootDir()) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(true, "PL-BI-1004", ROOT_DIR, message); isSuccess = false; return; } // 00_meta?? if (!isMetadataDir()) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(true, "PL-BI-1004", META_DIR, message); isSuccess = false; return; } // 00_meta??? ZipArchiveEntry zae = null; try { long maxBarEntryFileSize = getMaxBarEntryFileSize(); Set<String> keyList = barFileOrder.keySet(); while ((zae = this.zipArchiveInputStream.getNextZipEntry()) != null) { String entryName = zae.getName(); log.debug("Entry Name: " + entryName); log.debug("Entry Size: " + zae.getSize()); log.debug("Entry Compressed Size: " + zae.getCompressedSize()); if (!zae.isDirectory()) { this.progressInfo.addDelta(1L); } // bar?? isSuccess = createMetadata(zae, entryName, maxBarEntryFileSize, keyList, doneKeys); if (!isSuccess) { break; } // 90_contents?????? if (isContentsDir(zae)) { if (davCmpMap.isEmpty()) { writeOutputStream(true, "PL-BI-1004", zae.getName()); isSuccess = false; } else { writeOutputStream(false, "PL-BI-1003", zae.getName()); } doneKeys.add(zae.getName()); break; } } } catch (IOException ex) { isSuccess = false; log.info("IOException: " + ex.getMessage(), ex.fillInStackTrace()); } // 90_contents()??? if (isSuccess && isContentsDir(zae)) { isSuccess = createContents(); } // ?????????? // ??????? if (isSuccess) { Set<String> filenameList = barFileOrder.keySet(); for (String filename : filenameList) { Boolean isNecessary = barFileOrder.get(filename); if (isNecessary && !doneKeys.contains(filename)) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(true, "PL-BI-1004", filename, message); isSuccess = false; } } } } catch (Throwable ex) { isSuccess = false; String message = getErrorMessage(ex); log.info("Exception: " + message, ex.fillInStackTrace()); writeOutputStream(true, "PL-BI-1005", "", message); } finally { if (isSuccess) { writeOutputStream(false, CODE_BAR_INSTALL_COMPLETED, this.cell.getUrl() + boxName, ""); this.progressInfo.setStatus(ProgressInfo.STATUS.COMPLETED); } else { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(false, CODE_BAR_INSTALL_FAILED, this.cell.getUrl() + boxName, message); this.progressInfo.setStatus(ProgressInfo.STATUS.FAILED); } this.progressInfo.setEndTime(); writeToProgressCache(true); IOUtils.closeQuietly(this.zipArchiveInputStream); if (this.barFile.exists() && !this.barFile.delete()) { log.warn("Failed to remove bar file. [" + this.barFile.getAbsolutePath() + "]."); } } } /** * bar?????. */ private void setEventBus() { eventBus = new PersoniumEventBus(this.cell); JSONEvent reqBody = new JSONEvent(); reqBody.setAction(WebDAVMethod.MKCOL.toString()); reqBody.setLevel(LEVEL.INFO); reqBody.setObject(cell.getUrl() + boxName); reqBody.setResult(""); // TODO Box???????? this.event = EventResource.createEvent(reqBody, this.requestKey, odataEntityResource.getAccessContext()); } /** * ???. * @param ex * @return */ private String getErrorMessage(Throwable ex) { String message = ex.getMessage(); // ???????? if (message == null) { message = "throwed " + ex.getClass().getCanonicalName(); } return message; } /** * Zip????"bar/"?????. * @return "bar/"????true */ private boolean isRootDir() { return isMatchEntryName(ROOT_DIR); } /** * Zip????"bar/00_meta"?????. * @return "bar/00_meta"????true */ private boolean isMetadataDir() { return isMatchEntryName(META_DIR); } /** * Zip????"bar/90_contents"?????. * @param zae ZipArchiveEntry * @return "bar/90_contents"????true */ private boolean isContentsDir(ZipArchiveEntry zae) { boolean ret = false; if (zae == null) { ret = isMatchEntryName(CONTENTS_DIR); } else { ret = zae.getName().equals(CONTENTS_DIR); } return ret; } /** * Zip????????????????. * @param name ? * @return ???true */ private boolean isMatchEntryName(String name) { boolean ret = false; try { ZipArchiveEntry zae = this.zipArchiveInputStream.getNextZipEntry(); if (zae != null) { ret = zae.getName().equals(name); } } catch (IOException ex) { log.info("bar file entry was not read."); ret = false; } return ret; } /** * ?BAR?(MB)?? * @return io.personium.core.bar.entry.maxSize */ private long getMaxBarEntryFileSize() { long maxBarFileSize; try { maxBarFileSize = Long.parseLong(PersoniumUnitConfig.get(PersoniumUnitConfig.BAR.BAR_ENTRY_MAX_SIZE)); } catch (NumberFormatException ne) { log.info("NumberFormatException" + PersoniumUnitConfig.get(PersoniumUnitConfig.BAR.BAR_ENTRY_MAX_SIZE)); throw PersoniumCoreException.Server.UNKNOWN_ERROR; } return maxBarFileSize; } /** * bar?1????. * @param zae ZipArchiveEntry * @param entryName bar?? * @param maxSize ?(MB) * @param keyList * @param doneKeys * @return boolean ???? */ protected boolean createMetadata(ZipArchiveEntry zae, String entryName, long maxSize, Set<String> keyList, List<String> doneKeys) { if (!isValidFileStructure(zae, entryName, maxSize, doneKeys)) { return false; } if (getFileExtension(entryName).equals(".xml")) { // XML?? String boxUrl = this.box.getCell().getUrl() + this.box.getName(); if (!registXmlEntry(entryName, this.zipArchiveInputStream, boxUrl)) { doneKeys.add(entryName); return false; } writeOutputStream(false, "PL-BI-1003", entryName); doneKeys.add(entryName); return true; } if (getFileExtension(entryName).equals(".json")) { // JSON?? if (!registJsonEntry(entryName, this.zipArchiveInputStream)) { return false; } writeOutputStream(false, "PL-BI-1003", entryName); doneKeys.add(entryName); return true; } if (entryName.endsWith("/")) { return true; } return false; } /** * bar?(bar/90_contents)1????. * @return boolean ???? */ protected boolean createContents() { boolean isSuccess = true; // Collection???Map?????? Map<String, DavCmp> odataCols = getCollections(DavCmp.TYPE_COL_ODATA); Map<String, DavCmp> webdavCols = getCollections(DavCmp.TYPE_COL_WEBDAV); Map<String, DavCmp> serviceCols = getCollections(DavCmp.TYPE_COL_SVC); DavCmp davCmp = null; List<String> doneKeys = new ArrayList<String>(); try { ZipArchiveEntry zae = null; String currentPath = null; int userDataCount = 0; List<JSONMappedObject> userDataLinks = new ArrayList<JSONMappedObject>(); LinkedHashMap<String, BulkRequest> bulkRequests = new LinkedHashMap<String, BulkRequest>(); Map<String, String> fileNameMap = new HashMap<String, String>(); PersoniumODataProducer producer = null; while ((zae = this.zipArchiveInputStream.getNextZipEntry()) != null) { String entryName = zae.getName(); log.debug("Entry Name: " + entryName); log.debug("Entry Size: " + zae.getSize()); log.debug("Entry Compressed Size: " + zae.getCompressedSize()); if (!zae.isDirectory()) { this.progressInfo.addDelta(1L); } writeOutputStream(false, CODE_BAR_INSTALL_STARTED, entryName); // ODataCollection?Dav/ServiceCollection/ODataCollection????????? // ?????????? if (currentPath != null && !entryName.startsWith(currentPath)) { if (!execBulkRequest(davCmp.getCell().getId(), bulkRequests, fileNameMap, producer)) { return false; } if (!createUserdataLinks(producer, userDataLinks)) { return false; } userDataLinks = new ArrayList<JSONMappedObject>(); currentPath = null; } int entryType = getEntryType(entryName, odataCols, webdavCols, serviceCols, this.davFileMap); switch (entryType) { case TYPE_ODATA_COLLECTION: // OData? if (!odataCols.isEmpty()) { if (!isValidODataContents(entryName, odataCols, doneKeys)) { return false; } Pattern formatPattern = Pattern.compile(CONTENTS_DIR + ".+/90_data/"); Matcher formatMatcher = formatPattern.matcher(entryName); if (formatMatcher.matches()) { currentPath = entryName; } Pattern userodataDirPattern = Pattern.compile(CONTENTS_DIR + ".+/90_data/.+"); Matcher userodataDirMatcher = userodataDirPattern.matcher(entryName); if (getFileExtension(entryName).equals(".xml")) { // 00_$metadata.xml?? davCmp = getCollection(entryName, odataCols); // OData???????? producer = davCmp.getODataProducer(); if (!registUserSchema(entryName, this.zipArchiveInputStream, davCmp)) { doneKeys.add(entryName); return false; } writeOutputStream(false, "PL-BI-1003", entryName); doneKeys.add(entryName); continue; } else if (entryName.endsWith(USERDATA_LINKS_JSON)) { userDataLinks = registJsonLinksUserdata(entryName, this.zipArchiveInputStream); if (userDataLinks == null) { doneKeys.add(entryName); return false; } writeOutputStream(false, "PL-BI-1003", entryName); doneKeys.add(entryName); continue; } else if (userodataDirMatcher.matches() && getFileExtension(entryName).equals(".json")) { userDataCount++; if (!setBulkRequests(entryName, producer, bulkRequests, fileNameMap)) { return false; } doneKeys.add(entryName); if ((userDataCount % bulkSize) == 0 && !execBulkRequest(davCmp.getCell().getId(), bulkRequests, fileNameMap, producer)) { return false; } continue; } else if (!entryName.endsWith("/")) { // xml,json????????? String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); log.info(message + " [" + entryName + "]"); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } } break; case TYPE_DAV_FILE: // WebDAV? // bar/90_contents/{davcol_name}??1???? if (!registWebDavFile(entryName, this.zipArchiveInputStream, webdavCols)) { return false; } break; case TYPE_SVC_FILE: // Service? if (!installSvcCollection(webdavCols, entryName)) { return false; } break; case TYPE_MISMATCH: // OData??????????rootprops?????? String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2006"); log.info(message + " [" + entryName + "]"); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; default: break; } writeOutputStream(false, "PL-BI-1003", entryName); doneKeys.add(entryName); } // ODataCollection?????????????????? if (currentPath != null) { if (!execBulkRequest(davCmp.getCell().getId(), bulkRequests, fileNameMap, producer)) { return false; } if (!createUserdataLinks(producer, userDataLinks)) { return false; } userDataLinks = null; } } catch (IOException ex) { isSuccess = false; log.info("IOException: " + ex.getMessage(), ex.fillInStackTrace()); String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2000"); writeOutputStream(true, CODE_BAR_INSTALL_FAILED, "", message); } // bar/90_contents/{odatacol_name}/00_$metadata.xml)?? isSuccess = checkNecessaryFile(isSuccess, odataCols, doneKeys); return isSuccess; } private boolean checkNecessaryFile(boolean isSuccess, Map<String, DavCmp> odataCols, List<String> doneKeys) { Set<String> colList = odataCols.keySet(); for (String colName : colList) { String filename = colName + METADATA_XML; if (!doneKeys.contains(filename)) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(true, "PL-BI-1004", filename, message); isSuccess = false; } } return isSuccess; } private boolean installSvcCollection(Map<String, DavCmp> webdavCols, String entryName) { // bar/90_contents/{svccol_name}??1???WebDAV/???? // {serviceCollection}/{scriptName}{serviceCollection}/__src/{scriptName}?? int lastSlashIndex = entryName.lastIndexOf("/"); StringBuilder serviceSrcName = new StringBuilder(); serviceSrcName.append(entryName.substring(0, lastSlashIndex)); serviceSrcName.append("/__src"); serviceSrcName.append(entryName.substring(lastSlashIndex)); if (!registWebDavFile(serviceSrcName.toString(), this.zipArchiveInputStream, webdavCols)) { return false; } return true; } private boolean setBulkRequests(String entryName, PersoniumODataProducer producer, LinkedHashMap<String, BulkRequest> bulkRequests, Map<String, String> fileNameMap) { BulkRequest bulkRequest = new BulkRequest(); String key = PersoniumUUID.randomUUID(); try { // entityType???? String entityTypeName = getEntityTypeName(entryName); if (producer.getMetadata().findEdmEntitySet(entityTypeName) == null) { throw PersoniumCoreException.OData.NO_SUCH_ENTITY_SET; } // ZipArchiveImputStream??JSONStringReader???? StringReader stringReader = getStringReaderFromZais(); // ?? ODataResource odataResource = odataEntityResource.getOdataResource(); ODataEntitiesResource resource = new ODataEntitiesResource(odataResource, entityTypeName); OEntity oEntity = resource.getOEntityWrapper(stringReader, odataResource, producer.getMetadata()); UserDataODataProducer userDataProducer = (UserDataODataProducer) producer; EntitySetDocHandler docHandler = producer.getEntitySetDocHandler(entityTypeName, oEntity); String docType = UserDataODataProducer.USER_ODATA_NAMESPACE; docHandler.setType(docType); docHandler.setEntityTypeId(userDataProducer.getEntityTypeId(oEntity.getEntitySetName())); odataEntityResource.setOdataProducer(userDataProducer); // ??ID?? // TODO ?????NTKP key = oEntity.getEntitySetName() + ":" + (String) docHandler.getStaticFields().get("__id"); if (bulkRequests.containsKey(key)) { throw PersoniumCoreException.OData.ENTITY_ALREADY_EXISTS; } // ID?????UUID?? if (docHandler.getId() == null) { docHandler.setId(PersoniumUUID.randomUUID()); } bulkRequest.setEntitySetName(entityTypeName); bulkRequest.setDocHandler(docHandler); } catch (Exception e) { writeOutputStream(true, "PL-BI-1004", entryName, e.getMessage()); log.info(entryName + " : " + e.getMessage()); bulkRequest.setError(e); return false; } bulkRequests.put(key, bulkRequest); fileNameMap.put(key, entryName); return true; } private StringReader getStringReaderFromZais() throws IOException { BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(this.zipArchiveInputStream, "UTF-8")); StringBuffer buf = new StringBuffer(); String str = null; while ((str = bufferedReader.readLine()) != null) { buf.append(str); } StringReader stringReader = new StringReader(buf.toString()); return stringReader; } private String getEntityTypeName(String entryName) { String[] hierarchy = entryName.split("/"); int size = hierarchy.length; String entityTypeName = hierarchy[size - 2]; return entityTypeName; } private boolean execBulkRequest(String cellId, LinkedHashMap<String, BulkRequest> bulkRequests, Map<String, String> fileNameMap, PersoniumODataProducer producer) { // ?? producer.bulkCreateEntity(producer.getMetadata(), bulkRequests, cellId); // ??? for (Entry<String, BulkRequest> request : bulkRequests.entrySet()) { // ??????????? if (request.getValue().getError() != null) { if (request.getValue().getError() instanceof PersoniumCoreException) { PersoniumCoreException e = ((PersoniumCoreException) request.getValue().getError()); writeOutputStream(true, "PL-BI-1004", fileNameMap.get(request.getKey()), e.getMessage()); log.info("PersoniumCoreException: " + e.getMessage()); } else { Exception e = request.getValue().getError(); String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2003"); writeOutputStream(true, "PL-BI-1004", fileNameMap.get(request.getKey()), message); log.info("Regist Entity Error: " + e.toString()); log.info("Regist Entity Error: " + e.getClass().getName()); log.info("Regist Entity Error: " + e); } return false; } writeOutputStream(false, "PL-BI-1003", fileNameMap.get(request.getKey())); } bulkRequests.clear(); fileNameMap.clear(); return true; } /** * bar?90_contents?????. * @param entryName bar??? * @param odataCols OData? * @param webdavCols WebDAV? * @param serviceCols ? * @param davFiles WebDAV? * @return ? */ protected int getEntryType(String entryName, Map<String, DavCmp> odataCols, Map<String, DavCmp> webdavCols, Map<String, DavCmp> serviceCols, Map<String, String> davFiles) { if (odataCols.containsKey(entryName)) { return TYPE_ODATA_COLLECTION; } else if (webdavCols.containsKey(entryName)) { return TYPE_WEBDAV_COLLECTION; } else if (serviceCols.containsKey(entryName)) { return TYPE_SERVICE_COLLECTION; } else if (davFiles.containsKey(entryName)) { return TYPE_DAV_FILE; } for (Entry<String, DavCmp> entry : odataCols.entrySet()) { String odataColPath = entry.getKey(); if (entryName.startsWith(odataColPath)) { return TYPE_ODATA_COLLECTION; } } for (Entry<String, DavCmp> entry : serviceCols.entrySet()) { String serviceColPath = entry.getKey(); if (entryName.startsWith(serviceColPath)) { return TYPE_SVC_FILE; } } return TYPE_MISMATCH; } /** * WebDAV??. * @param entryName bar??? * @param inputStream * @param webdavCols WebDAV * @return true: ??false: */ protected boolean registWebDavFile(String entryName, InputStream inputStream, Map<String, DavCmp> webdavCols) { // ???? String filePath = entryName.replaceAll(CONTENTS_DIR, ""); String colPath = entryName.substring(0, entryName.lastIndexOf("/") + 1); // DavCmp? DavCmp parentCmp = webdavCols.get(colPath); // ??? int maxChildResource = PersoniumUnitConfig.getMaxChildResourceCount(); if (parentCmp.getChildrenCount() >= maxChildResource) { // ????????????? String message = PersoniumCoreMessageUtils.getMessage("PR400-DV-0007"); log.info(message); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } // ??? // ?? String fileName = ""; fileName = filePath.substring(filePath.lastIndexOf("/") + 1); // ? DavCmp fileCmp = parentCmp.getChild(fileName); // Content-Type?? String contentType = null; try { contentType = this.davFileMap.get(entryName); RuntimeDelegate.getInstance().createHeaderDelegate(MediaType.class).fromString(contentType); } catch (Exception e) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2005"); log.info(message + ": " + e.getMessage(), e.fillInStackTrace()); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } // try { fileCmp.putForCreate(contentType, new CloseShieldInputStream(inputStream)); } catch (Exception e) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2004"); log.info(message + ": " + e.getMessage(), e.fillInStackTrace()); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } return true; } /** * ?????. * @param filename ?? */ private String getFileExtension(String filename) { String extension = ""; int idx = filename.lastIndexOf("."); if (idx >= 0) { extension = filename.substring(idx); } return extension; } /** * 90_rootprops_xml???Collectoin/ACL/WebDAV???. * @param rootPropsName 90_rootprops_xml?bar?? * @param inputStream * @param boxUrl box?URL * @return ????true */ protected boolean registXmlEntry(String rootPropsName, InputStream inputStream, String boxUrl) { // XML(StAX,SAX,DOM)?InputStream??????????? // ????????????????? try { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); StringBuffer buf = new StringBuffer(); String str; while ((str = bufferedReader.readLine()) != null) { buf.append(str); } Multistatus multiStatus = Multistatus.unmarshal(new ByteArrayInputStream(buf.toString().getBytes())); // 90_rootprops.xml?????? // ????????????? if (!validateCollectionDefinitions(multiStatus, rootPropsName)) { return false; } for (Response response : multiStatus.getResponse()) { int collectionType = TYPE_WEBDAV_COLLECTION; boolean hasCollection = false; boolean isBox = false; List<String> hrefs = response.getHref(); String href = hrefs.get(0); if (href.equals("dcbox:")) { href = DCBOX; } if (href.equals(DCBOX)) { isBox = true; } String collectionUrl = null; collectionUrl = href.replaceFirst(DCBOX, boxUrl + "/"); List<Element> propElements = new ArrayList<Element>(); Element aclElement = null; String contentType = null; for (Propstat propstat : response.getPropstat()) { Prop prop = propstat.getProp(); Resourcetype resourceType = prop.getResourcetype(); if (resourceType != null) { if (resourceType.getCollection() != null) { hasCollection = true; } List<Element> elements = resourceType.getAny(); for (Element element : elements) { String nodeName = element.getNodeName(); if (nodeName.equals("p:odata")) { collectionType = TYPE_ODATA_COLLECTION; } else if (nodeName.equals("p:service")) { collectionType = TYPE_SERVICE_COLLECTION; } } } // prop?? Getcontenttype getContentType = prop.getGetcontenttype(); if (getContentType != null) { contentType = getContentType.getValue(); } List<Element> pElements = prop.getAny(); for (Element element : pElements) { String nodeName = element.getNodeName(); if (nodeName.equals("creationdate") || nodeName.equals("getlastmodified") || nodeName.equals("resourcetype")) { continue; } if (nodeName.equals("acl")) { if (!BarFileUtils.aclNameSpaceValidate(rootPropsName, element, this.schemaUrl)) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2007"); log.info(message + " [" + rootPropsName + "]"); writeOutputStream(true, "PL-BI-1004", rootPropsName, message); return false; } aclElement = element; continue; } propElements.add(element); } } String entryName = CONTENTS_DIR + href.replaceFirst(DCBOX, ""); if (isBox) { // Box???ACL registBoxAclAndProppatch(this.box, aclElement, propElements, collectionUrl); } else if (hasCollection) { if (!entryName.endsWith("/")) { entryName += "/"; } // ????ACL?PROPPATH log.info(entryName); createCollection(collectionUrl, entryName, this.cell, this.box, collectionType, aclElement, propElements); } else { // WebDAV this.davFileMap.put(entryName, contentType); } } } catch (PersoniumCoreException e) { log.info("PersoniumCoreException: " + e.getMessage()); writeOutputStream(true, "PL-BI-1004", rootPropsName, e.getMessage()); return false; } catch (Exception ex) { String message = getErrorMessage(ex); log.info("XMLParseException: " + message, ex.fillInStackTrace()); writeOutputStream(true, "PL-BI-1004", rootPropsName, message); return false; } return true; } /** * 90_rootprops.xml???path????????. * @param multiStatus 90_rootprops.xml???JAXB * @param rootPropsName ?????() * @return ?????true?????false? */ protected boolean validateCollectionDefinitions(Multistatus multiStatus, String rootPropsName) { // XML???href???OData/WebDAV/?WebDAV?)?? Map<String, Integer> pathMap = new LinkedHashMap<String, Integer>(); for (Response response : multiStatus.getResponse()) { List<String> hrefs = response.getHref(); if (hrefs.size() != 1) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2008"); writeOutputStream(true, "PL-BI-1004", rootPropsName, message); return false; } String href = hrefs.get(0); // href????????? if (href == null || href.length() == 0) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2009"); writeOutputStream(true, "PL-BI-1004", rootPropsName, message); return false; } // href???"dcbox:/" ?????????? if (!href.startsWith(DCBOX_NO_SLUSH)) { String message = MessageFormat.format(PersoniumCoreMessageUtils.getMessage("PL-BI-2010"), href); writeOutputStream(true, "PL-BI-1004", rootPropsName, message); return false; } // ???????????????? int collectionType = getCollectionType(rootPropsName, response); switch (collectionType) { case TYPE_WEBDAV_COLLECTION: case TYPE_ODATA_COLLECTION: case TYPE_SERVICE_COLLECTION: if (href.endsWith("/")) { href = href.substring(0, href.length() - 1); } break; case TYPE_MISMATCH: return false; default: break; } // ??????????????????? // ?"/"??????????? if (pathMap.containsKey(href)) { String message = MessageFormat.format(PersoniumCoreMessageUtils.getMessage("PL-BI-2011"), href); writeOutputStream(true, "PL-BI-1004", rootPropsName, message); return false; } pathMap.put(href, Integer.valueOf(collectionType)); } // ????Collection?? // Box???? // ?????? // OData?? ???????? // Service?? ?? "__src" ????? Set<String> keySet = pathMap.keySet(); for (Entry<String, Integer> entry : pathMap.entrySet()) { String href = entry.getKey(); int currentCollectionType = entry.getValue(); int upperPathposition = href.lastIndexOf("/"); if (upperPathposition < 0) { // "dcbox:"??????? continue; } // ???????????????? // Box??????????? String upper = href.substring(0, upperPathposition); if (!keySet.contains(upper)) { String message = MessageFormat.format(PersoniumCoreMessageUtils.getMessage("PL-BI-2012"), upper); writeOutputStream(true, "PL-BI-1004", rootPropsName, message); return false; } int upperCollectionType = pathMap.get(upper); String resourceName = href.substring(upperPathposition + 1, href.length()); if (upperCollectionType == TYPE_ODATA_COLLECTION) { // OData???????????? String message = MessageFormat.format(PersoniumCoreMessageUtils.getMessage("PL-BI-2013"), href); writeOutputStream(true, "PL-BI-1004", rootPropsName, message); return false; } else if (upperCollectionType == TYPE_SERVICE_COLLECTION) { // Service???????????? // ????"__src"??????? if (!("__src".equals(resourceName) && currentCollectionType == TYPE_WEBDAV_COLLECTION)) { String message = MessageFormat.format(PersoniumCoreMessageUtils.getMessage("PL-BI-2014"), href); writeOutputStream(true, "PL-BI-1004", rootPropsName, message); return false; } } else if (upperCollectionType == TYPE_DAV_FILE) { // WebDAV?Service???????????? String message = MessageFormat.format(PersoniumCoreMessageUtils.getMessage("PL-BI-2015"), href); writeOutputStream(true, "PL-BI-1004", rootPropsName, message); return false; } // ?Service?????"__src"?????????? if (currentCollectionType == TYPE_SERVICE_COLLECTION) { String srcPath = href + "/__src"; if (!keySet.contains(srcPath) || pathMap.get(srcPath) != TYPE_WEBDAV_COLLECTION) { String message = MessageFormat.format(PersoniumCoreMessageUtils.getMessage("PL-BI-2016"), href); writeOutputStream(true, "PL-BI-1004", rootPropsName, message); return false; } } // ????????????????? if (!DavCommon.isValidResourceName(resourceName)) { String message = MessageFormat.format(PersoniumCoreMessageUtils.getMessage("PL-BI-2017"), resourceName); writeOutputStream(true, "PL-BI-1004", rootPropsName, message); return false; } } return true; } /** * 90_rootprops.xml??response??????? * @param rootPropsName ?????() * @param response ??responseJAXB * @return ????? * WebDAV?Service?WebDAV???? * ?????????????????? */ private int getCollectionType(String rootPropsName, Response response) { // <propstat>??????????? // ?prop/resourcetype/collecton ?DOM???????? // ???"p:odata" ??? "p:service" ?DOM??????WebDAV???? // - ????????WebDAv??????? for (Propstat propstat : response.getPropstat()) { Prop prop = propstat.getProp(); Resourcetype resourceType = prop.getResourcetype(); if (resourceType != null && resourceType.getCollection() != null) { List<Element> elements = resourceType.getAny(); for (Element element : elements) { String nodeName = element.getNodeName(); if (nodeName.equals("p:odata")) { return TYPE_ODATA_COLLECTION; } else if (nodeName.equals("p:service")) { return TYPE_SERVICE_COLLECTION; } else { String message = MessageFormat.format(PersoniumCoreMessageUtils.getMessage("PL-BI-2018"), nodeName); writeOutputStream(true, "PL-BI-1004", rootPropsName, message); return TYPE_MISMATCH; } } } else { return TYPE_DAV_FILE; } } return TYPE_WEBDAV_COLLECTION; } /** * JSON???. * @param entryName ?? * @param inputStream * @return ????true */ private boolean registJsonEntry(String entryName, InputStream inputStream) { JsonParser jp = null; ObjectMapper mapper = new ObjectMapper(); JsonFactory f = new JsonFactory(); try { jp = f.createJsonParser(inputStream); JsonToken token = jp.nextToken(); // JSON?"{" Pattern formatPattern = Pattern.compile(".*/+(.*)"); Matcher formatMatcher = formatPattern.matcher(entryName); String jsonName = formatMatcher.replaceAll("$1"); if (token == JsonToken.START_OBJECT) { if (jsonName.equals(RELATION_JSON) || jsonName.equals(ROLE_JSON) || jsonName.equals(EXTROLE_JSON) || jsonName.equals(LINKS_JSON)) { registJsonEntityData(jp, mapper, jsonName); } else if (jsonName.equals(MANIFEST_JSON)) { manifestJsonValidate(jp, mapper); // Box????? } log.debug(jsonName); } else { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } } catch (PersoniumCoreException e) { // JSON?? writeOutputStream(true, "PL-BI-1004", entryName, e.getMessage()); log.info("PersoniumCoreException" + e.getMessage(), e.fillInStackTrace()); return false; } catch (JsonParseException e) { // JSON?? String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2002"); writeOutputStream(true, "PL-BI-1004", entryName, message); log.info("JsonParseException: " + e.getMessage(), e.fillInStackTrace()); return false; } catch (JsonMappingException e) { // JSON? String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2003"); writeOutputStream(true, "PL-BI-1004", entryName, message); log.info("JsonMappingException: " + e.getMessage(), e.fillInStackTrace()); return false; } catch (Exception e) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2000"); writeOutputStream(true, "PL-BI-1004", entryName, message); log.info("Exception: " + e.getMessage(), e.fillInStackTrace()); return false; } return true; } /** * 10_odatarelations.json????Link??. * @param entryName ?? * @param inputStream * @return ????true */ protected List<JSONMappedObject> registJsonLinksUserdata(String entryName, InputStream inputStream) { List<JSONMappedObject> userDataLinks = new ArrayList<JSONMappedObject>(); JsonParser jp = null; ObjectMapper mapper = new ObjectMapper(); JsonFactory f = new JsonFactory(); try { jp = f.createJsonParser(inputStream); JsonToken token = jp.nextToken(); // JSON?"{" if (token == JsonToken.START_OBJECT) { token = jp.nextToken(); // $links?? checkMatchFieldName(jp, USERDATA_LINKS_JSON); token = jp.nextToken(); // ????? if (token != JsonToken.START_ARRAY) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(USERDATA_LINKS_JSON); } token = jp.nextToken(); while (jp.hasCurrentToken()) { if (token == JsonToken.END_ARRAY) { break; } else if (token != JsonToken.START_OBJECT) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(USERDATA_LINKS_JSON); } userDataLinks.add(barFileJsonValidate(jp, mapper, USERDATA_LINKS_JSON)); token = jp.nextToken(); } } else { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(USERDATA_LINKS_JSON); } } catch (JsonParseException e) { // JSON?? String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2002"); writeOutputStream(true, "PL-BI-1004", entryName, message); log.info("JsonParseException: " + e.getMessage(), e.fillInStackTrace()); return null; } catch (JsonMappingException e) { // JSON? String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2003"); writeOutputStream(true, "PL-BI-1004", entryName, message); log.info("JsonMappingException: " + e.getMessage(), e.fillInStackTrace()); return null; } catch (PersoniumCoreException e) { // JSON?? writeOutputStream(true, "PL-BI-1004", entryName, e.getMessage()); log.info("PersoniumCoreException" + e.getMessage(), e.fillInStackTrace()); return null; } catch (IOException e) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2000"); writeOutputStream(true, "PL-BI-1004", entryName, message); log.info("IOException: " + e.getMessage(), e.fillInStackTrace()); return null; } return userDataLinks; } /** * ????????. * @param zae * @param entryName * @param maxSize * @param doneKeys * @return ???true? */ private boolean isValidFileStructure(ZipArchiveEntry zae, String entryName, long maxSize, List<String> doneKeys) { writeOutputStream(false, CODE_BAR_INSTALL_STARTED, entryName); // ??????? if (!barFileOrder.containsKey(entryName)) { log.info("[" + entryName + "] invalid file"); String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } // ????? Pattern formatPattern = Pattern.compile(".*/+([0-9][0-9])_.*"); Matcher formatMatcher = formatPattern.matcher(entryName); String entryIndex = formatMatcher.replaceAll("$1"); if (doneKeys.isEmpty()) { // ?????"00"????? if (!entryIndex.equals("00")) { log.info("bar/00_meta/00_manifest.json is not exsist"); String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } } else { String lastEntryName = doneKeys.get(doneKeys.size() - 1); formatMatcher = formatPattern.matcher(lastEntryName); String lastEntryIndex = formatMatcher.replaceAll("$1"); // ?????? if (entryIndex.compareTo(lastEntryIndex) < 0) { log.info("[" + entryName + "] invalid file"); String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } } // [400]bar/bar?????? if (zae.getSize() > (long) (maxSize * MB)) { log.info("Bar file entry size too large invalid file [" + entryName + "]"); String message = PersoniumCoreException.BarInstall.BAR_FILE_ENTRY_SIZE_TOO_LARGE .params(zae.getName(), String.valueOf(zae.getSize())).getMessage(); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } return true; } /** * bar/90_contents/{OdataCol_name}?????????????. * @param entryName ??(??) * @param colMap ?Map * @param doneKeys ???OData * @return ?? */ protected boolean isValidODataContents(String entryName, Map<String, DavCmp> colMap, List<String> doneKeys) { String odataColPath = ""; for (Map.Entry<String, DavCmp> entry : colMap.entrySet()) { if (entryName.startsWith(entry.getKey())) { odataColPath = entry.getKey(); break; } } // OData???? String odataPath = entryName.replaceAll(odataColPath, ""); // bar/90_contents/{OData_collection}??? if (USERDATA_LINKS_JSON.equals(odataPath)) { // 00_$metadata.xml???????? String meatadataPath = odataColPath + METADATA_XML; if (!doneKeys.contains(meatadataPath)) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); log.info(message + "entryName: " + entryName); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } // 90_data/?????????? String userDataPath = odataColPath + USERDATA_DIR_NAME + "/"; if (doneKeys.contains(userDataPath)) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); log.info(message + "entryName: " + entryName); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } } if (odataPath.startsWith(USERDATA_DIR_NAME + "/")) { // 00_$metadata.xml???????? String meatadataPath = odataColPath + METADATA_XML; if (!doneKeys.contains(meatadataPath)) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); log.info(message + "entryName: " + entryName); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } } // bar/90_contents/{OData_collection}/{dirPath}/?? String dirPath = null; Pattern pattern = Pattern.compile("^([^/]+)/.*"); Matcher m = pattern.matcher(odataPath); if (m.matches()) { dirPath = m.replaceAll("$1"); } if (dirPath != null && !dirPath.equals(USERDATA_DIR_NAME)) { // bar/90_contents/{OData_collection}/{dir}/????? String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); log.info(message + "entryName: " + entryName); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } // bar/90_contents/{OData_collection}/90_data/{entity}/{1.json}?? String fileName = null; pattern = Pattern.compile(".*/([^/]+)$"); m = pattern.matcher(odataPath); if (m.matches()) { fileName = m.replaceAll("$1"); } if (fileName != null) { pattern = Pattern.compile("^([0-9]+).json$"); m = pattern.matcher(fileName); if (!m.matches()) { // bar/90_contents/{OData_collection}/{dir}/????? String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); log.info(message + "entryName: " + entryName); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } } return true; } /** * 10_relations.json, 20_roles.json, 30_extroles.json, 70_$links.json, 10_odatarelations.json???. * @param jp Json * @param mapper ObjectMapper * @param jsonName ?? * @throws IOException IOException */ protected void registJsonEntityData(JsonParser jp, ObjectMapper mapper, String jsonName) throws IOException { JsonToken token; token = jp.nextToken(); // Relations,Roles,ExtRoles,$links?? checkMatchFieldName(jp, jsonName); token = jp.nextToken(); // ????? if (token != JsonToken.START_ARRAY) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } token = jp.nextToken(); while (jp.hasCurrentToken()) { if (token == JsonToken.END_ARRAY) { break; } else if (token != JsonToken.START_OBJECT) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } // 1? JSONMappedObject mappedObject = barFileJsonValidate(jp, mapper, jsonName); if (jsonName.equals(RELATION_JSON)) { createRelation(mappedObject.getJson()); } else if (jsonName.equals(ROLE_JSON)) { createRole(mappedObject.getJson()); } else if (jsonName.equals(EXTROLE_JSON)) { createExtRole(mappedObject.getJson()); } else if (jsonName.equals(LINKS_JSON)) { createLinks(mappedObject, odataProducer); } token = jp.nextToken(); } } /** * ???. * @param jp Json * @param mapper ObjectMapper * @param jsonName ?? * @throws IOException IOException * @return JSONMappedObject JSONMapped */ protected JSONMappedObject barFileJsonValidate(JsonParser jp, ObjectMapper mapper, String jsonName) throws IOException { if (jsonName.equals(EXTROLE_JSON)) { JSONExtRoles extRoles = mapper.readValue(jp, JSONExtRoles.class); if (extRoles.getExtRole() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } if (extRoles.getRelationName() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } return extRoles; } else if (jsonName.equals(ROLE_JSON)) { JSONRoles roles = mapper.readValue(jp, JSONRoles.class); if (roles.getName() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } return roles; } else if (jsonName.equals(RELATION_JSON)) { JSONRelations relations = mapper.readValue(jp, JSONRelations.class); if (relations.getName() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } return relations; } else if (jsonName.equals(LINKS_JSON)) { JSONLinks links = mapper.readValue(jp, JSONLinks.class); linksJsonValidate(jsonName, links); return links; } else if (jsonName.equals(USERDATA_LINKS_JSON)) { JSONUserDataLinks links = mapper.readValue(jp, JSONUserDataLinks.class); userDataLinksJsonValidate(jsonName, links); return links; } return null; } /** * 70_$links.json??. * @param jsonName JSON?? * @param links ??JSON */ private void linksJsonValidate(String jsonName, JSONLinks links) { if (links.getFromType() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } else { if (!links.getFromType().equals(Relation.EDM_TYPE_NAME) && !links.getFromType().equals(Role.EDM_TYPE_NAME) && !links.getFromType().equals(ExtRole.EDM_TYPE_NAME)) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } } if (links.getFromName() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } else { Map<String, String> fromNameMap = links.getFromName(); for (Map.Entry<String, String> entry : fromNameMap.entrySet()) { if (entry.getValue() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } } } if (links.getToType() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } else { if (!links.getToType().equals(Relation.EDM_TYPE_NAME) && !links.getToType().equals(Role.EDM_TYPE_NAME) && !links.getToType().equals(ExtRole.EDM_TYPE_NAME)) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } } if (links.getToName() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } else { Map<String, String> toNameMap = links.getToName(); for (Map.Entry<String, String> entry : toNameMap.entrySet()) { if (entry.getValue() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } } } } /** * 10_odatarelations.json??. * @param jsonName JSON?? * @param links ??JSON */ private void userDataLinksJsonValidate(String jsonName, JSONUserDataLinks links) { if (links.getFromType() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } if (links.getFromId() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } else { Map<String, String> fromIdMap = links.getFromId(); for (Map.Entry<String, String> entry : fromIdMap.entrySet()) { if (entry.getValue() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } } } if (links.getToType() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } if (links.getToId() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } else { Map<String, String> toIdMap = links.getToId(); for (Map.Entry<String, String> entry : toIdMap.entrySet()) { if (entry.getValue() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } } } } /** * manifest.json??. * @param jp Json * @param mapper ObjectMapper * @return JSONManifest * @throws IOException ??????? */ protected JSONManifest manifestJsonValidate(JsonParser jp, ObjectMapper mapper) throws IOException { // TODO BAR??? JSONManifest manifest = null; try { manifest = mapper.readValue(jp, JSONManifest.class); } catch (UnrecognizedPropertyException ex) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR .params("manifest.json unrecognized property"); } if (manifest.getBarVersion() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params("manifest.json#barVersion"); } if (manifest.getBoxVersion() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params("manifest.json#boxVersion"); } if (manifest.getDefaultPath() == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params("manifest.json#DefaultPath"); } return manifest; } /** * ????????????. * @param jp * @param jsonName * @throws IOException * @throws JsonParseException */ private void checkMatchFieldName(JsonParser jp, String jsonName) throws IOException { String fieldName = jp.getCurrentName(); if (!(fieldName.equals("Relations") && jsonName.equals(RELATION_JSON)) && !(fieldName.equals("Roles") && jsonName.equals(ROLE_JSON)) && !(fieldName.equals("ExtRoles") && jsonName.equals(EXTROLE_JSON)) && !(fieldName.equals("Links") && jsonName.equals(LINKS_JSON)) && !(fieldName.equals("Links") && jsonName.equals(USERDATA_LINKS_JSON))) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(jsonName); } } /** * Http??. * @param isError ???true????false?. * @param code * (personium-messages.properties???) * @param path * ?ex. /bar/meta/roles.json) */ private void writeOutputStream(boolean isError, String code, String path) { writeOutputStream(isError, code, path, ""); } /** * bar?. * @param isError ???true????false?. * @param code * (personium-messages.properties???) * @param path * ?ex. /bar/meta/roles.json) * @param detail * ??(PL-BI-2xxx) */ private void writeOutputStream(boolean isError, String code, String path, String detail) { String message = PersoniumCoreMessageUtils.getMessage(code); if (detail == null) { message = message.replace("{0}", ""); } else { message = message.replace("{0}", detail); } outputEventBus(isError, code, path, message); String output = String.format("\"%s\",\"%s\",\"%s\"", code, path, message); log.info(output); } /** * ???EventBus????. * @param isError ???true????false?. * @param code ?ex. PL-BI-0000 * @param path bar?Edmx????OData? * @param message */ @SuppressWarnings("unchecked") private void outputEventBus(boolean isError, String code, String path, String message) { if (event != null) { event.setAction(code); event.setObject(path); event.setResult(message); eventBus.outputEventLog(event); } if (this.progressInfo != null && isError) { JSONObject messageJson = new JSONObject(); JSONObject messageDetail = new JSONObject(); messageJson.put("code", code); messageJson.put("message", messageDetail); messageDetail.put("lang", "en"); messageDetail.put("value", message); this.progressInfo.setMessage(messageJson); writeToProgressCache(true); } else { writeToProgressCache(false); } } /** * ?bar??. * @param forceOutput ????true????false? */ private void writeToProgressCache(boolean forceOutput) { if (this.progressInfo != null && this.progressInfo.isOutputEventBus() || forceOutput) { String key = "box-" + this.box.getId(); Progress progress = new Progress(key, progressInfo.toString()); ProgressManager.putProgress(key, progress); log.info("Progress(" + key + "): " + progressInfo.toString()); } } private void setupBarFileOrder() { barFileOrder = new LinkedHashMap<String, Boolean>(); barFileOrder.put("bar/00_meta/00_manifest.json", true); barFileOrder.put("bar/00_meta/10_relations.json", false); barFileOrder.put("bar/00_meta/20_roles.json", false); barFileOrder.put("bar/00_meta/30_extroles.json", false); barFileOrder.put("bar/00_meta/70_$links.json", false); barFileOrder.put("bar/00_meta/90_rootprops.xml", true); barFileOrder.put("bar/90_contents/", false); // dummy } private String createdBoxEtag = ""; private String createdBoxName = ""; /** * ???Box????. * @return ?? */ public String getCreatedBoxName() { return createdBoxName; } /** * ???Box?ETag?. * @return ETag */ public String getCreatedBoxETag() { return createdBoxEtag; } /** * BoxES??. * @param json JSON???JSON */ @SuppressWarnings("unchecked") void createBox(JSONObject json) { if (boxName == null || boxName.isEmpty()) { this.createdBoxName = (String) json.get("Name"); } else { json.put("Name", boxName); this.createdBoxName = boxName; } StringReader stringReader = new StringReader(json.toJSONString()); OEntityWrapper oew = odataEntityResource.getOEntityWrapper(stringReader, odataEntityResource.getOdataResource(), CtlSchema.getEdmDataServicesForCellCtl().build()); // Box? odataProducer.createEntity(entitySetName, oew); this.createdBoxEtag = oew.getEtag(); // Dav? Box newBox = new Box(odataEntityResource.getAccessContext().getCell(), oew); this.boxCmp = ModelFactory.boxCmp(newBox); this.box = newBox; this.schemaUrl = (String) json.get("Schema"); } /** * 10_$relations.json????RelationES??. * @param json JSON???JSON */ @SuppressWarnings("unchecked") private void createRelation(JSONObject json) { json.put("_Box.Name", createdBoxName); StringReader stringReader = new StringReader(json.toJSONString()); odataEntityResource.setEntitySetName(Relation.EDM_TYPE_NAME); OEntityWrapper oew = odataEntityResource.getOEntityWrapper(stringReader, odataEntityResource.getOdataResource(), CtlSchema.getEdmDataServicesForCellCtl().build()); // Relation? odataProducer.createEntity(Relation.EDM_TYPE_NAME, oew); } /** * 20_$roles.json????RoleES??. * @param json JSON???JSON */ @SuppressWarnings("unchecked") private void createRole(JSONObject json) { json.put("_Box.Name", createdBoxName); StringReader stringReader = new StringReader(json.toJSONString()); odataEntityResource.setEntitySetName(Role.EDM_TYPE_NAME); OEntityWrapper oew = odataEntityResource.getOEntityWrapper(stringReader, odataEntityResource.getOdataResource(), CtlSchema.getEdmDataServicesForCellCtl().build()); // Role? odataProducer.createEntity(Role.EDM_TYPE_NAME, oew); } /** * 30_$extroles.json????ExtRoleES??. * @param json JSON???JSON */ @SuppressWarnings("unchecked") private void createExtRole(JSONObject json) { String url = (String) json.get(ExtRole.EDM_TYPE_NAME); json.put(ExtRole.EDM_TYPE_NAME, url); json.put("_Relation._Box.Name", createdBoxName); StringReader stringReader = new StringReader(json.toJSONString()); odataEntityResource.setEntitySetName(ExtRole.EDM_TYPE_NAME); OEntityWrapper oew = odataEntityResource.getOEntityWrapper(stringReader, odataEntityResource.getOdataResource(), CtlSchema.getEdmDataServicesForCellCtl().build()); // ExtRole? odataProducer.createEntity(ExtRole.EDM_TYPE_NAME, oew); } /** * 70_$links.json????ES??. * @param mappedObject JSON??? */ private void createLinks(JSONMappedObject mappedObject, PersoniumODataProducer producer) { Map<String, String> fromNameMap = ((JSONLinks) mappedObject).getFromName(); String fromkey = BarFileUtils.getComplexKeyName(((JSONLinks) mappedObject).getFromType(), fromNameMap, this.boxName); OEntityKey fromOEKey = OEntityKey.parse(fromkey); OEntityId sourceEntity = OEntityIds.create(((JSONLinks) mappedObject).getFromType(), fromOEKey); String targetNavProp = ((JSONLinks) mappedObject).getNavPropToType(); // ??? odataEntityResource.getOdataResource().beforeLinkCreate(sourceEntity, targetNavProp); Map<String, String> toNameMap = ((JSONLinks) mappedObject).getToName(); String tokey = BarFileUtils.getComplexKeyName(((JSONLinks) mappedObject).getToType(), toNameMap, this.boxName); OEntityKey toOEKey = OEntityKey.parse(tokey); OEntityId newTargetEntity = OEntityIds.create(((JSONLinks) mappedObject).getToType(), toOEKey); // $links? producer.createLink(sourceEntity, targetNavProp, newTargetEntity); } private boolean createUserdataLinks(PersoniumODataProducer producer, List<JSONMappedObject> userDataLinks) { int linkSize = userDataLinks.size(); int linkCount = 0; String message = PersoniumCoreMessageUtils.getMessage("PL-BI-1002"); for (JSONMappedObject json : userDataLinks) { linkCount++; if (!createUserdataLink(json, producer)) { return false; } if (linkCount % linksOutputStreamSize == 0) { writeOutputStream(false, "PL-BI-1002", String.format("userDataLinks %d / %d", linkCount, linkSize), message); } } writeOutputStream(false, "PL-BI-1002", String.format("userDataLinks %d / %d", linkCount, linkSize), message); return true; } /** * 10_odatarelations.json????ES??. * @param mappedObject JSON??? */ private boolean createUserdataLink(JSONMappedObject mappedObject, PersoniumODataProducer producer) { OEntityId sourceEntity = null; OEntityId newTargetEntity = null; try { Map<String, String> fromId = ((JSONUserDataLinks) mappedObject).getFromId(); String fromKey = ""; Iterator<Entry<String, String>> fromIterator = fromId.entrySet().iterator(); fromKey = String.format("('%s')", fromIterator.next().getValue()); OEntityKey fromOEKey = OEntityKey.parse(fromKey); sourceEntity = OEntityIds.create(((JSONUserDataLinks) mappedObject).getFromType(), fromOEKey); String targetNavProp = ((JSONUserDataLinks) mappedObject).getNavPropToType(); // ??? odataEntityResource.getOdataResource().beforeLinkCreate(sourceEntity, targetNavProp); Map<String, String> toId = ((JSONUserDataLinks) mappedObject).getToId(); String toKey = ""; Iterator<Entry<String, String>> toIterator = toId.entrySet().iterator(); toKey = String.format("('%s')", toIterator.next().getValue()); OEntityKey toOEKey = OEntityKey.parse(toKey); newTargetEntity = OEntityIds.create(((JSONUserDataLinks) mappedObject).getToType(), toOEKey); // $links? producer.createLink(sourceEntity, targetNavProp, newTargetEntity); } catch (Exception e) { String path = ""; String targetPath = ""; if (sourceEntity != null) { path = sourceEntity.getEntitySetName() + sourceEntity.getEntityKey(); } if (newTargetEntity != null) { targetPath = "Target Link to " + newTargetEntity.getEntitySetName() + newTargetEntity.getEntityKey(); } log.info(e.getMessage() + " [" + path + "]", e.fillInStackTrace()); writeOutputStream(true, "PL-BI-1004", path, targetPath); return false; } return true; } private void createCollection(String collectionUrl, String entryName, Cell parentCell, Box parentBox, int collectionType, Element aclElement, List<Element> propElements) { int index; if (parentCell == null || parentBox == null) { return; } String type = ""; switch (collectionType) { case TYPE_WEBDAV_COLLECTION: type = DavCmp.TYPE_COL_WEBDAV; break; case TYPE_ODATA_COLLECTION: type = DavCmp.TYPE_COL_ODATA; break; case TYPE_SERVICE_COLLECTION: type = DavCmp.TYPE_COL_SVC; break; default: break; } String parenEntryName = ""; DavCmp parentCmp = null; String tmp = entryName.replace(CONTENTS_DIR, "/"); String[] slash = tmp.split("/"); if (slash.length == 2) { parentCmp = this.boxCmp; } else { index = entryName.lastIndexOf("/", entryName.length() - 2); parenEntryName = entryName.substring(0, index + 1); parentCmp = this.davCmpMap.get(parenEntryName); if (parentCmp == null) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(entryName); } else if (parentCmp.getType().equals(DavCmp.TYPE_COL_ODATA)) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(entryName); } else if (parentCmp.getType().equals(DavCmp.TYPE_COL_SVC)) { String crrName = entryName.substring(index + 1, entryName.length() - 1); if (!"__src".equals(crrName)) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(entryName); } } } // String parentId = parentCmp.getId(); // // ??? // DavCmp current = parentCmp; // // // current???????????depth???1 // int depth = 1; // int maxDepth = PersoniumCoreConfig.getMaxCollectionDepth(); // while (null != current.getParent()) { // current = (DavCmp) current.getParent(); // depth++; // } // if (depth > maxDepth) { // // ???????400?? // throw PersoniumCoreException.Dav.COLLECTION_DEPTH_ERROR; // } // // // ??? // int maxChildResource = PersoniumCoreConfig.getMaxChildResourceCount(); // if (parentCmp.getChildrenCount() >= maxChildResource) { // // ???????????400?? // throw PersoniumCoreException.Dav.COLLECTION_CHILDRESOURCE_ERROR; // } // // ?? String collectionName = ""; index = collectionUrl.lastIndexOf("/"); collectionName = collectionUrl.substring(index + 1); DavCmp collectionCmp = parentCmp.getChild(collectionName); collectionCmp.mkcol(type); this.davCmpMap.put(entryName, collectionCmp); // ACL if (aclElement != null) { String baseUrl = uriInfo.getBaseUri().toASCIIString(); Element convElement = BarFileUtils.convertToRoleInstanceUrl(aclElement, baseUrl, this.cell.getName(), this.boxName); StringBuffer sbAclXml = new StringBuffer(); sbAclXml.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>"); sbAclXml.append(PersoniumCoreUtils.nodeToString(convElement)); Reader aclXml = new StringReader(sbAclXml.toString()); collectionCmp.acl(aclXml); } // PROPPATCH registProppatch(collectionCmp, propElements, collectionUrl); } /** * Box?ACL?PROPPATCH. * @param targetBox box * @param aclElement ACL * @param propElements PROPATCH?? * @param boxUrl box?URL */ private void registBoxAclAndProppatch(Box targetBox, Element aclElement, List<Element> propElements, String boxUrl) { if (targetBox == null || boxCmp == null) { return; } // ACL if (aclElement != null) { String baseUrl = uriInfo.getBaseUri().toASCIIString(); Element convElement = BarFileUtils.convertToRoleInstanceUrl(aclElement, baseUrl, this.cell.getName(), this.boxName); StringBuffer sbAclXml = new StringBuffer(); sbAclXml.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>"); sbAclXml.append(PersoniumCoreUtils.nodeToString(convElement)); Reader aclXml = new StringReader(sbAclXml.toString()); boxCmp.acl(aclXml); } // PROPPATCH registProppatch(boxCmp, propElements, boxUrl); } private void registProppatch(DavCmp davCmp, List<Element> propElements, String boxUrl) { if (!propElements.isEmpty()) { Reader propXml = getProppatchXml(propElements); try { Propertyupdate propUpdate = Propertyupdate.unmarshal(propXml); davCmp.proppatch(propUpdate, boxUrl); } catch (IOException ex) { throw PersoniumCoreException.Dav.XML_ERROR.reason(ex); } } } /** * bar?????Map<key, DavCmpEsImpl>??. * @return ?MapDavCmpEsImpl */ private Map<String, DavCmp> getCollections(String colType) { Map<String, DavCmp> map = new HashMap<String, DavCmp>(); Set<String> keySet = davCmpMap.keySet(); for (String key : keySet) { DavCmp davCmp = davCmpMap.get(key); if (davCmp != null && colType.equals(davCmp.getType())) { map.put(key, davCmp); } } return map; } /** * bar?????Map<key, DavCmpEsImpl>??. * @param entryName ?? * @param collections ?Map * @return ?MapDavCmpEsImpl */ private DavCmp getCollection(String entryName, Map<String, DavCmp> collections) { int pos = entryName.lastIndexOf("/"); if (pos == entryName.length() - 1) { return collections.get(entryName); } String colName = entryName.substring(0, pos + 1); return collections.get(colName); } /** * 00_$metadata_xml??????. * @param entryName ?? * @param inputStream * @param davCmp Collection? * @return ????true */ protected boolean registUserSchema(String entryName, InputStream inputStream, DavCmp davCmp) { EdmDataServices metadata = null; // XML(StAX,SAX,DOM)?InputStream??????????? // ????????????????? try { InputStreamReader isr = new InputStreamReader(new CloseShieldInputStream(inputStream)); // 00_$metadata.xml???? XMLFactoryProvider2 provider = StaxXMLFactoryProvider2.getInstance(); XMLInputFactory2 factory = provider.newXMLInputFactory2(); XMLEventReader2 reader = factory.createXMLEventReader(isr); PersoniumEdmxFormatParser parser = new PersoniumEdmxFormatParser(); metadata = parser.parseMetadata(reader); } catch (Exception ex) { log.info("XMLParseException: " + ex.getMessage(), ex.fillInStackTrace()); String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2002"); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } catch (StackOverflowError tw) { // ComplexType???StackOverFlowError?? log.info("XMLParseException: " + tw.getMessage(), tw.fillInStackTrace()); String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2002"); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } // Entity/Property? // Property/ComplexProperty????ComplexType??????? // ??ComplexType????EntityType? // PersoniumODataProducer producer = davCmp.getODataProducer(); try { createComplexTypes(metadata, davCmp); createEntityTypes(metadata, davCmp); createAssociations(metadata, davCmp); } catch (PersoniumCoreException e) { writeOutputStream(true, "PL-BI-1004", entryName, e.getMessage()); log.info("PersoniumCoreException: " + e.getMessage()); return false; } catch (Exception e) { log.info("Regist Entity Error: " + e.getMessage(), e.fillInStackTrace()); String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2003"); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } return true; } /** * Edmx????EntityType/Property?. * @param metadata Edmx? * @param davCmp Collection? */ @SuppressWarnings("unchecked") protected void createEntityTypes(EdmDataServices metadata, DavCmp davCmp) { // DeclaredProperty?EntityType????????EntityType???Property? Iterable<EdmEntityType> entityTypes = metadata.getEntityTypes(); UserSchemaODataProducer producer = null; EdmDataServices userMetadata = null; for (EdmEntityType entity : entityTypes) { log.debug("EntityType: " + entity.getName()); if (producer == null) { producer = (UserSchemaODataProducer) davCmp.getSchemaODataProducer(this.cell); userMetadata = CtlSchema.getEdmDataServicesForODataSvcSchema().build(); } Map<String, String> entityTypeIds = producer.getEntityTypeIds(); odataEntityResource.setEntitySetName(EntityType.EDM_TYPE_NAME); JSONObject json = new JSONObject(); json.put("Name", entity.getName()); StringReader stringReader = new StringReader(json.toJSONString()); OEntityWrapper oew = odataEntityResource.getOEntityWrapper(stringReader, odataEntityResource.getOdataResource(), userMetadata); // EntityType? String path = String.format("/%s/%s/%s/EntityType('%s')", this.cell.getName(), this.boxName, davCmp.getName(), entity.getName()); writeOutputStream(false, "PL-BI-1002", path); EntityResponse response = producer.createEntity(EntityType.EDM_TYPE_NAME, oew); OEntityWrapper entityResponse = (OEntityWrapper) response.getEntity(); entityTypeIds.put(entity.getName(), entityResponse.getUuid()); } // EntityType?????Property? for (EdmEntityType entity : entityTypes) { createProperties(entity, davCmp, producer); } } /** * Edmx????Property/ComplexTypeProperty?. * @param entity ?Property????EntityType/ComplexType * @param davCmp Collection? * @param producer OData */ @SuppressWarnings("unchecked") protected void createProperties(EdmStructuralType entity, DavCmp davCmp, PersoniumODataProducer producer) { Iterable<EdmProperty> properties = entity.getDeclaredProperties(); EdmDataServices userMetadata = null; String edmTypeName = Property.EDM_TYPE_NAME; if (entity instanceof EdmComplexType) { edmTypeName = ComplexTypeProperty.EDM_TYPE_NAME; } for (EdmProperty property : properties) { String name = property.getName(); log.debug(edmTypeName + ": " + name); if (name.startsWith("_")) { continue; } if (userMetadata == null) { userMetadata = CtlSchema.getEdmDataServicesForODataSvcSchema().build(); odataEntityResource.setEntitySetName(edmTypeName); } CollectionKind kind = property.getCollectionKind(); if (kind != null && !kind.equals(CollectionKind.NONE) && !kind.equals(CollectionKind.List)) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(METADATA_XML); } JSONObject json = new JSONObject(); json.put("Name", property.getName()); if (entity instanceof EdmComplexType) { json.put("_ComplexType.Name", entity.getName()); } else { json.put("_EntityType.Name", entity.getName()); json.put("IsKey", false); // Iskey???? json.put("UniqueKey", null); // UniqueKey???? } String typeName = property.getType().getFullyQualifiedTypeName(); if (!property.getType().isSimple() && typeName.startsWith("UserData.")) { typeName = typeName.replace("UserData.", ""); } json.put("Type", typeName); json.put("Nullable", property.isNullable()); json.put("DefaultValue", property.getDefaultValue()); json.put("CollectionKind", property.getCollectionKind().toString()); StringReader stringReader = new StringReader(json.toJSONString()); OEntityWrapper oew = odataEntityResource.getOEntityWrapper(stringReader, odataEntityResource.getOdataResource(), userMetadata); // ComplexTypeProperty? producer.createEntity(edmTypeName, oew); } } /** * Edmx????AssociationEnd???. * @param metadata Edmx? * @param davCmp Collection? */ protected void createAssociations(EdmDataServices metadata, DavCmp davCmp) { Iterable<EdmAssociation> associations = metadata.getAssociations(); PersoniumODataProducer producer = null; EdmDataServices userMetadata = null; for (EdmAssociation association : associations) { // Association???AssociationEnd?AssociationEnd??? String name = association.getName(); log.debug("Association: " + name); if (producer == null) { producer = davCmp.getSchemaODataProducer(this.cell); userMetadata = CtlSchema.getEdmDataServicesForODataSvcSchema().build(); odataEntityResource.setEntitySetName(AssociationEnd.EDM_TYPE_NAME); } String path = String.format("/%s/%s/%s/Association('%s','%s')", this.cell.getName(), this.boxName, davCmp.getName(), association.getEnd1().getRole(), association.getEnd2().getRole()); writeOutputStream(false, "PL-BI-1002", path); // AssociationEnd? EdmAssociationEnd ae1 = association.getEnd1(); String realRoleName1 = getRealRoleName(ae1.getRole()); createAssociationEnd(producer, userMetadata, ae1, realRoleName1); EdmAssociationEnd ae2 = association.getEnd2(); String realRoleName2 = getRealRoleName(ae2.getRole()); createAssociationEnd(producer, userMetadata, ae2, realRoleName2); // AssociationEnd?$links String fromkey = String.format("(Name='%s',_EntityType.Name='%s')", realRoleName1, ae1.getType().getName()); OEntityKey fromOEKey = OEntityKey.parse(fromkey); OEntityId sourceEntity = OEntityIds.create(AssociationEnd.EDM_TYPE_NAME, fromOEKey); String targetNavProp = "_" + AssociationEnd.EDM_TYPE_NAME; odataEntityResource.getOdataResource().beforeLinkCreate(sourceEntity, targetNavProp); String tokey = String.format("(Name='%s',_EntityType.Name='%s')", realRoleName2, ae2.getType().getName()); OEntityKey toOEKey = OEntityKey.parse(tokey); OEntityId newTargetEntity = OEntityIds.create(AssociationEnd.EDM_TYPE_NAME, toOEKey); producer.createLink(sourceEntity, targetNavProp, newTargetEntity); } } /* * ("??:??")?????? * ??????????? * @param sourceRoleName ???? ("??:??") * @return ??? */ private String getRealRoleName(String sourceRoleName) { String[] tokens = sourceRoleName.split(":"); if (tokens.length != 2) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(sourceRoleName); } if (tokens[0].length() <= 0 || tokens[1].length() <= 0) { throw PersoniumCoreException.BarInstall.JSON_FILE_FORMAT_ERROR.params(sourceRoleName); } return tokens[1]; } /** * ???AssociationEnd?. * @param producer EntityPersoniumODataProcucer * @param userMetadata * @param associationEnd AssociationEnd * @param associationEndName AssociationEnd?? */ @SuppressWarnings("unchecked") protected void createAssociationEnd(PersoniumODataProducer producer, EdmDataServices userMetadata, EdmAssociationEnd associationEnd, String associationEndName) { // AssociationEnd??????AssociationEnd???? JSONObject json = new JSONObject(); String entityTypeName = associationEnd.getType().getName(); json.put(AssociationEnd.P_ASSOCIATION_NAME.getName(), associationEndName); json.put(AssociationEnd.P_ENTITYTYPE_NAME.getName(), entityTypeName); json.put(AssociationEnd.P_MULTIPLICITY.getName(), associationEnd.getMultiplicity().getSymbolString()); StringReader stringReader = new StringReader(json.toJSONString()); OEntityWrapper oew = odataEntityResource.getOEntityWrapper(stringReader, odataEntityResource.getOdataResource(), userMetadata); producer.createEntity(AssociationEnd.EDM_TYPE_NAME, oew); } /** * Edmx????ComplexType/ComplexTypeProperty?. * @param metadata Edmx? * @param davCmp Collection? */ @SuppressWarnings("unchecked") protected void createComplexTypes(EdmDataServices metadata, DavCmp davCmp) { // DeclaredProperty?ComplexType????????ComplexType???ComplexTypeProperty? Iterable<EdmComplexType> complexTypes = metadata.getComplexTypes(); PersoniumODataProducer producer = null; EdmDataServices userMetadata = null; for (EdmComplexType complexType : complexTypes) { log.debug("ComplexType: " + complexType.getName()); if (producer == null) { producer = davCmp.getSchemaODataProducer(this.cell); userMetadata = CtlSchema.getEdmDataServicesForODataSvcSchema().build(); } odataEntityResource.setEntitySetName(ComplexType.EDM_TYPE_NAME); JSONObject json = new JSONObject(); json.put("Name", complexType.getName()); StringReader stringReader = new StringReader(json.toJSONString()); OEntityWrapper oew = odataEntityResource.getOEntityWrapper(stringReader, odataEntityResource.getOdataResource(), userMetadata); // ComplexType? String path = String.format("/%s/%s/%s/ComplexType('%s')", this.cell.getName(), this.boxName, davCmp.getName(), complexType.getName()); writeOutputStream(false, "PL-BI-1002", path); producer.createEntity(ComplexType.EDM_TYPE_NAME, oew); } // ComplexType?????ComplexTypeProperty? for (EdmComplexType complexType : complexTypes) { createProperties(complexType, davCmp, producer); } } private Reader getProppatchXml(List<Element> propElements) { StringBuffer sbPropXml = new StringBuffer(); sbPropXml.append("<D:propertyupdate xmlns:D=\"DAV:\""); sbPropXml.append(" xmlns:p=\"urn:x-personium:xmlns\""); sbPropXml.append(" xmlns:Z=\"http://www.w3.com/standards/z39.50/\">"); sbPropXml.append("<D:set>"); sbPropXml.append("<D:prop>"); for (Element element : propElements) { sbPropXml.append(PersoniumCoreUtils.nodeToString(element)); } sbPropXml.append("</D:prop>"); sbPropXml.append("</D:set>"); sbPropXml.append("</D:propertyupdate>"); Reader propXml = new StringReader(sbPropXml.toString()); return propXml; } /** * @param entryCount the entryCount to set */ void setEntryCount(long entryCount) { this.progressInfo = new BarInstallProgressInfo(this.cell.getId(), this.box.getId(), entryCount); } /** * ??????. */ public void writeInitProgressCache() { setEventBus(); writeOutputStream(false, "PL-BI-1000", this.cell.getUrl() + boxName, ""); writeToProgressCache(true); } /** * ??. */ public void writeErrorProgressCache() { if (this.progressInfo != null) { this.progressInfo.setStatus(ProgressInfo.STATUS.FAILED); this.progressInfo.setEndTime(); writeToProgressCache(true); } } }