gt:                         String filename = entry.getSymbolicName();
context: package eu.unifiedviews.plugins.swc.transformer.conceptextractor;
  
  import eu.unifiedviews.dataunit.DataUnit;
  import eu.unifiedviews.dataunit.DataUnitException;
  import eu.unifiedviews.dataunit.files.FilesDataUnit;
  import eu.unifiedviews.dataunit.rdf.RDFDataUnit;
  import eu.unifiedviews.dataunit.rdf.WritableRDFDataUnit;
  import eu.unifiedviews.dpu.DPU;
  import eu.unifiedviews.dpu.DPUException;
  import eu.unifiedviews.helpers.dataunit.DataUnitUtils;
  import eu.unifiedviews.helpers.dataunit.files.FilesHelper;
  import eu.unifiedviews.helpers.dataunit.rdf.RdfDataUnitUtils;
  import eu.unifiedviews.helpers.dpu.config.ConfigHistory;
  import eu.unifiedviews.helpers.dpu.context.ContextUtils;
  import eu.unifiedviews.helpers.dpu.exec.AbstractDpu;
  import eu.unifiedviews.helpers.dpu.extension.ExtensionInitializer;
  import eu.unifiedviews.helpers.dpu.extension.faulttolerance.FaultTolerance;
  import eu.unifiedviews.helpers.dpu.extension.faulttolerance.FaultToleranceUtils;
  import eu.unifiedviews.helpers.dpu.extension.rdf.simple.WritableSimpleRdf;
  import org.apache.http.HttpHost;
  import org.apache.http.HttpStatus;
  import org.apache.http.auth.AuthScope;
  import org.apache.http.auth.UsernamePasswordCredentials;
  import org.apache.http.client.AuthCache;
  import org.apache.http.client.CredentialsProvider;
  import org.apache.http.client.methods.CloseableHttpResponse;
  import org.apache.http.client.methods.HttpGet;
  import org.apache.http.client.methods.HttpPost;
  import org.apache.http.client.protocol.HttpClientContext;
  import org.apache.http.entity.ContentType;
  import org.apache.http.entity.mime.HttpMultipartMode;
  import org.apache.http.entity.mime.MultipartEntityBuilder;
  import org.apache.http.impl.auth.BasicScheme;
  import org.apache.http.impl.client.BasicAuthCache;
  import org.apache.http.impl.client.BasicCredentialsProvider;
  import org.apache.http.impl.client.CloseableHttpClient;
  import org.apache.http.impl.client.HttpClients;
  import org.apache.http.util.EntityUtils;
  import org.openrdf.model.*;
  import org.openrdf.model.impl.*;
  import org.openrdf.repository.RepositoryConnection;
  import org.openrdf.repository.RepositoryResult;
  import org.openrdf.rio.RDFFormat;
  import org.openrdf.rio.RDFParser;
  import org.openrdf.rio.Rio;
  import org.openrdf.rio.helpers.StatementCollector;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.io.File;
  import java.io.StringReader;
  import java.io.UnsupportedEncodingException;
  import java.net.URLEncoder;
  import java.nio.charset.StandardCharsets;
  import java.util.*;
  
  /**
   * Main data processing unit class.
   *
   * @author Yang Yuanzhe
   */
  @DPU.AsTransformer
  public class ConceptExtractor extends AbstractDpu<ConceptExtractorConfig_V1> {
      private static final String PPX_NS = "http://schema.semantic-web.at/ppx/";
      private static final URI PPX_RESPONSE_CODE = new URIImpl("http://schema.semantic-web.at/ppx/responseCode");
      private static final URI PPX_MESSAGE = new URIImpl("http://schema.semantic-web.at/ppx/message");
      private static final URI PPX_FILE_NAME = new URIImpl("http://schema.semantic-web.at/ppx/fileName");
      private static final Logger LOG = LoggerFactory.getLogger(ConceptExtractor.class);
  
      public Set<Statement> graphStatements = null;
      public Map<String, String> filenameUriMappings = null;
      public URI graphUri = null;
      public Set<Statement> failedExtractionResourceStatements = null;
      public Set<Statement> failedExtractionReasonStatements = null;
      public Map<String, File> failedExtractionFiles = null;
  		
      @ExtensionInitializer.Init
      public FaultTolerance faultTolerance;
  
      @DataUnit.AsInput(name = "rdfInput", optional = true)
      public RDFDataUnit rdfInput;
  
      @DataUnit.AsInput(name = "fileInput", optional = true)
      public FilesDataUnit fileInput;
  
      @DataUnit.AsOutput(name = "rdfOutput")
      public WritableRDFDataUnit rdfOutput;
  
      @DataUnit.AsOutput(name = "failedExtractionOutput", optional = true)
      public WritableRDFDataUnit failedExtractionOutput;
  
      @ExtensionInitializer.Init(param = "rdfOutput")
      public WritableSimpleRdf rdfWrapper;
  
      @ExtensionInitializer.Init(param = "failedExtractionOutput")
      public WritableSimpleRdf failedExtractionWrapper;
  
  	public ConceptExtractor() {
  		super(ConceptExtractorVaadinDialog.class, ConfigHistory.noHistory(ConceptExtractorConfig_V1.class));
  	}
  
      /**
       * DPU execution entrypoint
       * @throws DPUException
       */
      @Override
      protected void innerExecute() throws DPUException {
          if (fileInput == null && rdfInput == null) {
              throw new DPUException("Input data is not provided for this DPU");
          }
  
          final RDFDataUnit.Entry outputEntry = faultTolerance.execute(new FaultTolerance.ActionReturn<RDFDataUnit.Entry>() {
  
              @Override
              public RDFDataUnit.Entry action() throws Exception {
                  return RdfDataUnitUtils.addGraph(rdfOutput, DataUnitUtils.generateSymbolicName(this.getClass()));
              }
          });
          rdfWrapper.setOutput(outputEntry);
          final RDFDataUnit.Entry failedExtractionEntry = faultTolerance.execute(new FaultTolerance.ActionReturn<RDFDataUnit.Entry>() {
  
              @Override
              public RDFDataUnit.Entry action() throws Exception {
                  return RdfDataUnitUtils.addGraph(failedExtractionOutput, DataUnitUtils.generateSymbolicName(this.getClass()));
              }
          });
          failedExtractionWrapper.setOutput(failedExtractionEntry);
  
          ContextUtils.sendShortInfo(ctx, "Prepare for concept extraction");
          String serviceUrl = config.getExtractionServiceUrl();
          HttpStateWrapper httpWrapper = createHttpStateWithAuth();
  
          ContextUtils.sendShortInfo(ctx, "Check extraction model status");
          requestExtractionModelUpdateService(httpWrapper);
  
          failedExtractionResourceStatements = new HashSet<>();
          failedExtractionReasonStatements = new HashSet<>();
          failedExtractionFiles = new HashMap<>();
  
          // when concept extraction target is string literals of RDF statements
          if (fileInput == null && rdfInput != null) {
              final List<RDFDataUnit.Entry> entries = FaultToleranceUtils.getEntries(faultTolerance, rdfInput, RDFDataUnit.Entry.class);
              for (RDFDataUnit.Entry entry : entries) {
                  graphUri = FaultToleranceUtils.asGraph(faultTolerance, entry);
                  ContextUtils.sendShortInfo(ctx, "Start loading statements from graph " + graphUri.toString());
                  loadGraphStatements(graphUri);
                  ContextUtils.sendShortInfo(ctx, "Finish loading");
                  ContextUtils.sendShortInfo(ctx, "Start extracting objects from graph " + graphUri.toString());
                  executeConceptExtraction(serviceUrl, httpWrapper);
                  ContextUtils.sendShortInfo(ctx, "Finish extraction");
              }
          }
          // when concept extraction target is files
          else {
              // prepare mapping when URIs for files are provided
              if (rdfInput != null) {
                  final List<RDFDataUnit.Entry> entries = FaultToleranceUtils.getEntries(faultTolerance, rdfInput, RDFDataUnit.Entry.class);
                  if (entries.size() > 1) {
                      throw new DPUException("Concept extraction on files must be provided with one file input and no more " +
                              "than one RDF input denoting file URIs");
                  } else if (entries.size() == 1) {
                      graphUri = FaultToleranceUtils.asGraph(faultTolerance, entries.get(0));
                      ContextUtils.sendShortInfo(ctx, "Start loading filenames from graph " + graphUri.toString());
                      loadFilenameUriMappings(graphUri);
                      ContextUtils.sendShortInfo(ctx, "Finish loading");
                  }
              }
              ContextUtils.sendShortInfo(ctx, "Start extracting files");
              executeConceptExtraction(serviceUrl, httpWrapper);
              ContextUtils.sendShortInfo(ctx, "Finish extraction");
          }
  
          int retriedTimes = 0;
          int numberOfFailedExtractions = 0;
          // retry failed extractions when retry times is less than its limit, failed extraction exists, and any failed
          // extraction becomes successful during previous retry
          while (retriedTimes < config.getMaxRetry() && !failedExtractionResourceStatements.isEmpty()
                  && failedExtractionResourceStatements.size() != numberOfFailedExtractions) {
              numberOfFailedExtractions = failedExtractionResourceStatements.size();
              retriedTimes++;
              ContextUtils.sendShortInfo(ctx, "Retry failed extractions, Iteration " + retriedTimes);
              retryFailedExtractions(serviceUrl, httpWrapper);
          }
  
          ContextUtils.sendShortInfo(ctx, "All extraction tasks accomplished, failed extractions: "
                  + numberOfFailedExtractions);
  
          rdfWrapper.flushBuffer();
          failedExtractionWrapper.add(new ArrayList<>(failedExtractionResourceStatements));
          failedExtractionWrapper.add(new ArrayList<>(failedExtractionReasonStatements));
          failedExtractionWrapper.flushBuffer();
      }
  
      /**
       * Retry failed extractions to tolerate network failures
       * @param serviceUrl URL of concept extraction service
       * @param httpWrapper wrapped HTTP state used for requests
       */
      private void retryFailedExtractions(String serviceUrl, HttpStateWrapper httpWrapper) throws DPUException {
          failedExtractionReasonStatements.clear();
          for (Statement s : new HashSet<>(failedExtractionResourceStatements)) {
              if (s.getPredicate().equals(PPX_FILE_NAME) && failedExtractionFiles.containsKey(s.getObject().stringValue())) {
                  extractSingleFile(failedExtractionFiles.get(s.getObject().stringValue()), s.getSubject().stringValue(),
                          serviceUrl, httpWrapper);
              } else {
                  extractSingleObject(s, serviceUrl, httpWrapper);
              }
          }
      }
  
      /**
       * Read all the statements in the given graph
       * @param graphUri URI of the graph
       * @throws DPUException
       */
      private void loadGraphStatements(final URI graphUri) throws DPUException {
          graphStatements = new HashSet<>();
          faultTolerance.execute(rdfInput, new FaultTolerance.ConnectionAction() {
              @Override
              public void action(RepositoryConnection connection) throws Exception {
                  RepositoryResult<Statement> repositoryResult = connection.getStatements(null, null, null, false, graphUri);
                  graphStatements.clear();
                  while (repositoryResult.hasNext()) {
                      if (ctx.canceled()) {
                          throw ContextUtils.dpuExceptionCancelled(ctx);
                      }
                      graphStatements.add(repositoryResult.next());
                  }
  
              }
          });
      }
  
      /**
       * Read filename to URI mappings from the given graph
       * @param graphUri URI of the graph
       * @throws DPUException
       */
      private void loadFilenameUriMappings(final URI graphUri) throws DPUException {
          filenameUriMappings = new HashMap<>();
          faultTolerance.execute(rdfInput, new FaultTolerance.ConnectionAction() {
              @Override
              public void action(RepositoryConnection connection) throws Exception {
                  RepositoryResult<Statement> repositoryResult = connection.getStatements(null, null, null, false, graphUri);
                  filenameUriMappings.clear();
                  while (repositoryResult.hasNext()) {
                      if (ctx.canceled()) {
                          throw ContextUtils.dpuExceptionCancelled(ctx);
                      }
                      Statement filenameStmt = repositoryResult.next();
                      filenameUriMappings.put(filenameStmt.getObject().stringValue(), filenameStmt.getSubject().stringValue());
                  }
  
              }
          });
      }
  
      /**
       * Execute concept extraction for files or string literals in the RDF statements
       * @throws DPUException
       */
      private void executeConceptExtraction(String serviceUrl, HttpStateWrapper httpWrapper) throws DPUException {
          if (graphStatements != null && !graphStatements.isEmpty()) {
              int graphSize = graphStatements.size();
              int blockSize = graphSize/10 > 0 ? graphSize/10 : 1;
              int reportIndex = blockSize;
              int index = 0;
              for (Statement statement : graphStatements) {
                  if (ctx.canceled()) {
                      throw ContextUtils.dpuExceptionCancelled(ctx);
                  }
                  extractSingleObject(statement, serviceUrl, httpWrapper);
                  index++;
                  if (index >= reportIndex) {
                      reportIndex += blockSize;
                      ContextUtils.sendShortInfo(ctx, "Extracted " + index + " of " + graphSize + " texts");
                  }
              }
          } else if (fileInput != null) {
              final List<FilesDataUnit.Entry> fileEntries = FaultToleranceUtils.getEntries(faultTolerance, fileInput, FilesDataUnit.Entry.class);
              int fileSize = fileEntries.size();
              int blockSize = fileSize/10 > 0 ? fileSize/10 : 1;
              int reportIndex = blockSize;
              int index = 0;
              // use URIs for files provided from the file name to URI mappings
              if (filenameUriMappings != null && !filenameUriMappings.isEmpty()) {
                  for (FilesDataUnit.Entry entry : fileEntries) {
                      if (ctx.canceled()) {
                          throw ContextUtils.dpuExceptionCancelled(ctx);
                      }
                      try {
  