@Override
  public UploadModelResult upload(byte[] content, String fileName) {
    try {
      ModelResource resource =
          ModelParserFactory.getParser(fileName).parse(new ByteArrayInputStream(content));

      for (IModelValidator validator : validators) {
        validator.validate(resource);
      }
      return UploadModelResult.valid(
          createUploadHandle(resource.getId(), content, fileName), resource);
    } catch (ValidationException validationException) {
      return UploadModelResult.invalid(validationException);
    }
  }
 @Override
 public void removeModel(ModelId modelId) {
   try {
     ModelResource modelResource = getById(modelId);
     if (!modelResource.getReferencedBy().isEmpty()) {
       throw new ModelReferentialIntegrityException(
           "Cannot remove model because it is referenced by other model(s)",
           modelResource.getReferencedBy());
     }
     Item item = session.getItem(modelId.getFullPath());
     item.remove();
     session.save();
   } catch (RepositoryException e) {
     throw new FatalModelRepositoryException("Problem occured removing the model", e);
   }
 }
 private boolean isTargetPlatformMapping(ModelResource model, String targetPlatform) {
   try {
     ModelEMFResource emfResource = getEMFResource(model.getId());
     return emfResource.matchesTargetPlatform(targetPlatform);
   } catch (Exception e) {
     throw new FatalModelRepositoryException("Something went wrong accessing the repository", e);
   }
 }
 @Override
 public ModelResource getById(ModelId modelId) {
   try {
     Node foundNode = session.getNode(modelId.getFullPath());
     Node fileNode = (Node) foundNode.getNodes().next();
     ModelResource modelResource = createModelResource(fileNode);
     if (modelResource.getModelType() == ModelType.InformationModel) {
       for (ModelId referencedById : modelResource.getReferencedBy()) {
         ModelEMFResource emfResource = getEMFResource(referencedById);
         modelResource.addTargetPlatform(emfResource.getTargetPlatform());
       }
     }
     return modelResource;
   } catch (PathNotFoundException e) {
     return null;
   } catch (RepositoryException e) {
     throw new RuntimeException("Retrieving Content of Resource: Problem accessing repository", e);
   }
 }
 @Override
 public List<ModelResource> getMappingModelsForTargetPlatform(
     ModelId modelId, String targetPlatform) {
   List<ModelResource> mappingResources = new ArrayList<>();
   ModelResource modelResource = getById(modelId);
   if (modelResource != null) {
     for (ModelId referenceeModelId : modelResource.getReferencedBy()) {
       ModelResource referenceeModelResources = getById(referenceeModelId);
       if (referenceeModelResources.getModelType() == ModelType.Mapping
           && isTargetPlatformMapping(referenceeModelResources, targetPlatform)) {
         mappingResources.add(referenceeModelResources);
       }
     }
     for (ModelId referencedModelId : modelResource.getReferences()) {
       mappingResources.addAll(
           getMappingModelsForTargetPlatform(referencedModelId, targetPlatform));
     }
   }
   return mappingResources;
 }
  private ModelResource createModelResource(Node node) throws RepositoryException {
    ModelResource resource =
        new ModelResource(
            ModelId.fromPath(node.getParent().getPath()),
            ModelType.valueOf(node.getProperty("vorto:type").getString()));
    resource.setDescription(node.getProperty("vorto:description").getString());
    resource.setDisplayName(node.getProperty("vorto:displayname").getString());
    resource.setCreationDate(node.getProperty("jcr:created").getDate().getTime());
    if (node.hasProperty("vorto:author")) {
      resource.setAuthor(node.getProperty("vorto:author").getString());
    }

    if (node.hasProperty("vorto:references")) {
      Value[] referenceValues = node.getProperty("vorto:references").getValues();
      if (referenceValues != null) {
        ModelReferencesHelper referenceHelper = new ModelReferencesHelper();
        for (Value referValue : referenceValues) {
          String nodeUuid = referValue.getString();
          Node referencedNode = session.getNodeByIdentifier(nodeUuid);
          referenceHelper.addModelReference(
              ModelId.fromPath(referencedNode.getParent().getPath()).getPrettyFormat());
        }
        resource.setReferences(referenceHelper.getReferences());
      }
    }

    PropertyIterator propIter = node.getReferences();
    while (propIter.hasNext()) {
      Property prop = propIter.nextProperty();
      Node referencedByFileNode = prop.getParent();
      final ModelId referencedById = ModelId.fromPath(referencedByFileNode.getParent().getPath());
      resource.getReferencedBy().add(referencedById);
    }

    return resource;
  }
  @Override
  public void checkin(String handleId) {
    InputStream contentAsStream;
    final File uploadedFile;
    try {
      uploadedFile = loadUploadedFile(handleId);
      logger.debug("Found temporary file for handleId : " + uploadedFile.getName());
      contentAsStream = new FileInputStream(uploadedFile);
    } catch (FileNotFoundException e1) {
      throw new ModelNotFoundException(
          "Could not find uploaded model with the specified handle", e1);
    }

    final ModelResource resource =
        ModelParserFactory.getParser(uploadedFile.getName()).parse(contentAsStream);

    try {
      governance.start(
          new ModelUploadHandle(
              resource.getId(),
              resource.getModelType(),
              IOUtils.toByteArray(new FileInputStream(uploadedFile))),
          new IGovernanceCallback() {

            @Override
            public void processUploadResult(GovernanceResult uploadResult) {
              if (uploadResult.isApproved()) {
                try {
                  logger.debug(
                      "Checkin for "
                          + uploadResult.getHandle().getModelId().getPrettyFormat()
                          + " was approved. Proceeding with checkin...");
                  Node folderNode = createNodeForModelId(uploadResult.getHandle().getModelId());
                  Node fileNode =
                      folderNode.addNode(
                          uploadResult.getHandle().getModelId().getName()
                              + uploadResult.getHandle().getModelType().getExtension(),
                          "nt:file");
                  fileNode.addMixin("vorto:meta");
                  fileNode.addMixin("mix:referenceable");
                  Node contentNode = fileNode.addNode("jcr:content", "nt:resource");
                  Binary binary =
                      session
                          .getValueFactory()
                          .createBinary(
                              new ByteArrayInputStream(uploadResult.getHandle().getContent()));
                  contentNode.setProperty("jcr:data", binary);
                  session.save();
                  logger.debug("Checkin successful.");
                  FileUtils.deleteQuietly(uploadedFile);
                } catch (RepositoryException e) {
                  throw new RuntimeException(e);
                }
              } else {
                logger.warn(resource.getId().getPrettyFormat() + " was not approved for checkin");
              }
            }
          });
    } catch (IOException e) {
      throw new RuntimeException("Something went wrong when reading the model content", e);
    }
  }