Exemplo n.º 1
0
  @Override
  public void removeCollection(Context context, Community community, Collection collection)
      throws SQLException, AuthorizeException, IOException {
    // Check authorisation
    authorizeService.authorizeAction(context, community, Constants.REMOVE);

    community.removeCollection(collection);
    ArrayList<String> removedIdentifiers = collectionService.getIdentifiers(context, collection);
    String removedHandle = collection.getHandle();
    UUID removedId = collection.getID();

    collection.removeCommunity(community);
    if (CollectionUtils.isEmpty(collection.getCommunities())) {
      collectionService.delete(context, collection);
    }

    log.info(
        LogManager.getHeader(
            context,
            "remove_collection",
            "community_id=" + community.getID() + ",collection_id=" + collection.getID()));

    // Remove any mappings
    context.addEvent(
        new Event(
            Event.REMOVE,
            Constants.COMMUNITY,
            community.getID(),
            Constants.COLLECTION,
            removedId,
            removedHandle,
            removedIdentifiers));
  }
  @Override
  public Group getWorkflowRoleGroup(
      Context context, Collection collection, String roleName, Group roleGroup)
      throws SQLException, AuthorizeException {
    if ("WF_STEP1".equals(roleName)) {
      roleGroup = collection.getWorkflowStep1();
      if (roleGroup == null)
        roleGroup = collectionService.createWorkflowGroup(context, collection, 1);

    } else if ("WF_STEP2".equals(roleName)) {
      roleGroup = collection.getWorkflowStep2();
      if (roleGroup == null)
        roleGroup = collectionService.createWorkflowGroup(context, collection, 2);
    } else if ("WF_STEP3".equals(roleName)) {
      roleGroup = collection.getWorkflowStep3();
      if (roleGroup == null)
        roleGroup = collectionService.createWorkflowGroup(context, collection, 3);
    }
    return roleGroup;
  }
Exemplo n.º 3
0
  /**
   * GET request is only ever used to show the upload form
   *
   * @param context a DSpace Context object
   * @param request the HTTP request
   * @param response the HTTP response
   * @throws ServletException
   * @throws IOException
   * @throws SQLException
   * @throws AuthorizeException
   */
  @Override
  protected void doDSGet(Context context, HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException, SQLException, AuthorizeException {
    // Get all collections
    List<Collection> collections = null;
    String colIdS = request.getParameter("colId");
    if (colIdS != null) {
      collections = new ArrayList<>();
      collections.add(collectionService.findByIdOrLegacyId(context, colIdS));

    } else {
      collections = collectionService.findAll(context);
    }

    request.setAttribute("collections", collections);

    // Get all the possible data loaders from the Spring configuration
    BTEBatchImportService dls = new DSpace().getSingletonService(BTEBatchImportService.class);
    List<String> inputTypes = dls.getFileDataLoaders();
    request.setAttribute("input-types", inputTypes);

    // Show the upload screen
    JSPManager.showJSP(request, response, "/dspace-admin/batchimport.jsp");
  }
Exemplo n.º 4
0
  /**
   * Respond to a post request for metadata bulk importing via csv
   *
   * @param context a DSpace Context object
   * @param request the HTTP request
   * @param response the HTTP response
   * @throws ServletException
   * @throws IOException
   * @throws SQLException
   * @throws AuthorizeException
   */
  @Override
  protected void doDSPost(Context context, HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException, SQLException, AuthorizeException {

    // First, see if we have a multipart request (uploading a metadata file)
    String contentType = request.getContentType();
    if ((contentType != null) && (contentType.indexOf("multipart/form-data") != -1)) {
      String message = null;

      // Process the file uploaded
      try {
        // Wrap multipart request to get the submission info
        FileUploadRequest wrapper = new FileUploadRequest(request);

        String inputType = wrapper.getParameter("inputType");
        List<String> reqCollectionsTmp =
            getRepeatedParameter(wrapper, "collections", "collections");
        String[] reqCollections = new String[reqCollectionsTmp.size()];
        reqCollectionsTmp.toArray(reqCollections);

        // Get all collections
        List<Collection> collections = null;
        String colIdS = wrapper.getParameter("colId");
        if (colIdS != null) {
          collections = new ArrayList<>();
          collections.add(collectionService.findByIdOrLegacyId(context, colIdS));

        } else {
          collections = collectionService.findAll(context);
        }
        request.setAttribute("collections", collections);

        Collection owningCollection = null;
        if (wrapper.getParameter("collection") != null) {
          owningCollection =
              collectionService.findByIdOrLegacyId(context, wrapper.getParameter("collection"));
        }

        // Get all the possible data loaders from the Spring configuration
        BTEBatchImportService dls = new DSpace().getSingletonService(BTEBatchImportService.class);
        List<String> inputTypes = dls.getFileDataLoaders();
        request.setAttribute("input-types", inputTypes);

        if (reqCollectionsTmp != null) request.setAttribute("otherCollections", reqCollectionsTmp);
        if (owningCollection != null)
          request.setAttribute("owningCollection", owningCollection.getID());
        request.setAttribute("inputType", inputType);

        File f = null;
        String zipurl = null;

        if (inputType.equals("saf")) {
          zipurl = wrapper.getParameter("zipurl");
          if (StringUtils.isEmpty(zipurl)) {
            request.setAttribute("has-error", "true");
            Locale locale = request.getLocale();
            ResourceBundle msgs = ResourceBundle.getBundle("Messages", locale);
            try {
              message = msgs.getString("jsp.layout.navbar-admin.batchimport.fileurlempty");
            } catch (Exception e) {
              message = "???jsp.layout.navbar-admin.batchimport.fileurlempty???";
            }

            request.setAttribute("message", message);

            JSPManager.showJSP(request, response, "/dspace-admin/batchimport.jsp");

            return;
          }
        } else {
          f = wrapper.getFile("file");
          if (f == null) {
            request.setAttribute("has-error", "true");
            Locale locale = request.getLocale();
            ResourceBundle msgs = ResourceBundle.getBundle("Messages", locale);
            try {
              message = msgs.getString("jsp.layout.navbar-admin.batchimport.fileempty");
            } catch (Exception e) {
              message = "???jsp.layout.navbar-admin.batchimport.fileempty???";
            }

            request.setAttribute("message", message);

            JSPManager.showJSP(request, response, "/dspace-admin/batchimport.jsp");

            return;
          } else if (owningCollection == null) {
            request.setAttribute("has-error", "true");
            Locale locale = request.getLocale();
            ResourceBundle msgs = ResourceBundle.getBundle("Messages", locale);
            try {
              message = msgs.getString("jsp.layout.navbar-admin.batchimport.owningcollectionempty");
            } catch (Exception e) {
              message = "???jsp.layout.navbar-admin.batchimport.owningcollectionempty???";
            }

            request.setAttribute("message", message);

            JSPManager.showJSP(request, response, "/dspace-admin/batchimport.jsp");

            return;
          }
        }

        String uploadId = wrapper.getParameter("uploadId");
        if (uploadId != null) {
          request.setAttribute("uploadId", uploadId);
        }

        if (owningCollection == null && reqCollections != null && reqCollections.length > 0) {
          request.setAttribute("has-error", "true");

          Locale locale = request.getLocale();
          ResourceBundle msgs = ResourceBundle.getBundle("Messages", locale);
          String ms = msgs.getString("jsp.layout.navbar-admin.batchimport.owningcollection");
          if (ms == null) {
            ms = "???jsp.layout.navbar-admin.batchimport.owningcollection???";
          }
          request.setAttribute("message", ms);

          JSPManager.showJSP(request, response, "/dspace-admin/batchimport.jsp");

          return;
        }

        try {
          String finalInputType = "saf";
          String filePath = zipurl;
          if (f != null) {
            finalInputType = inputType;
            filePath = f.getAbsolutePath();
          }

          itemImportService.processUIImport(
              filePath, owningCollection, reqCollections, uploadId, finalInputType, context, true);

          request.setAttribute("has-error", "false");
          request.setAttribute("uploadId", null);

        } catch (Exception e) {
          request.setAttribute("has-error", "true");
          message = e.getMessage();
          e.printStackTrace();
        }
      } catch (FileSizeLimitExceededException e) {
        request.setAttribute("has-error", "true");
        message = e.getMessage();
        e.printStackTrace();
      } catch (Exception e) {
        request.setAttribute("has-error", "true");
        message = e.getMessage();
        e.printStackTrace();
      }

      request.setAttribute("message", message);

      // Show the upload screen
      JSPManager.showJSP(request, response, "/dspace-admin/batchimport.jsp");

    } else {
      request.setAttribute("has-error", "true");

      // Show the upload screen
      JSPManager.showJSP(request, response, "/dspace-admin/batchimport.jsp");
    }
  }
  @Override
  public void addInitialWorkspaceItemPolicies(Context context, WorkspaceItem workspaceItem)
      throws SQLException, AuthorizeException {
    // Now create the policies for the submitter and workflow
    // users to modify item and contents
    // contents = bitstreams, bundles
    // FIXME: icky hardcoded workflow steps
    Collection collection = workspaceItem.getCollection();
    Group step1group = collectionService.getWorkflowGroup(collection, 1);
    Group step2group = collectionService.getWorkflowGroup(collection, 2);
    Group step3group = collectionService.getWorkflowGroup(collection, 3);

    Item item = workspaceItem.getItem();

    if (step1group != null) {
      authorizeService.addPolicy(
          context, item, Constants.READ, step1group, ResourcePolicy.TYPE_WORKFLOW);
    }

    if (step2group != null) {
      authorizeService.addPolicy(
          context, item, Constants.READ, step2group, ResourcePolicy.TYPE_WORKFLOW);
    }

    if (step3group != null) {
      authorizeService.addPolicy(
          context, item, Constants.READ, step3group, ResourcePolicy.TYPE_WORKFLOW);
    }

    if (step1group != null) {
      authorizeService.addPolicy(
          context, item, Constants.WRITE, step1group, ResourcePolicy.TYPE_WORKFLOW);
    }

    if (step2group != null) {
      authorizeService.addPolicy(
          context, item, Constants.WRITE, step2group, ResourcePolicy.TYPE_WORKFLOW);
    }

    if (step3group != null) {
      authorizeService.addPolicy(
          context, item, Constants.WRITE, step3group, ResourcePolicy.TYPE_WORKFLOW);
    }

    if (step1group != null) {
      authorizeService.addPolicy(
          context, item, Constants.ADD, step1group, ResourcePolicy.TYPE_WORKFLOW);
    }

    if (step2group != null) {
      authorizeService.addPolicy(
          context, item, Constants.ADD, step2group, ResourcePolicy.TYPE_WORKFLOW);
    }

    if (step3group != null) {
      authorizeService.addPolicy(
          context, item, Constants.ADD, step3group, ResourcePolicy.TYPE_WORKFLOW);
    }

    if (step1group != null) {
      authorizeService.addPolicy(
          context, item, Constants.REMOVE, step1group, ResourcePolicy.TYPE_WORKFLOW);
    }

    if (step2group != null) {
      authorizeService.addPolicy(
          context, item, Constants.REMOVE, step2group, ResourcePolicy.TYPE_WORKFLOW);
    }

    if (step3group != null) {
      authorizeService.addPolicy(
          context, item, Constants.REMOVE, step3group, ResourcePolicy.TYPE_WORKFLOW);
    }
  }
  // returns true if archived
  protected boolean doState(
      Context context, BasicWorkflowItem workflowItem, int newstate, EPerson newowner)
      throws SQLException, IOException, AuthorizeException {
    Collection mycollection = workflowItem.getCollection();
    Group mygroup = null;
    boolean archived = false;

    // Gather our old data for launching the workflow event
    int oldState = workflowItem.getState();

    workflowItem.setState(newstate);

    switch (newstate) {
      case WFSTATE_STEP1POOL:

        // any reviewers?
        // if so, add them to the tasklist
        workflowItem.setOwner(null);

        // get reviewers (group 1 )
        mygroup = collectionService.getWorkflowGroup(mycollection, 1);

        if ((mygroup != null) && !(groupService.isEmpty(mygroup))) {
          // get a list of all epeople in group (or any subgroups)
          List<EPerson> epa = groupService.allMembers(context, mygroup);

          // there were reviewers, change the state
          //  and add them to the list
          createTasks(context, workflowItem, epa);
          workflowItemService.update(context, workflowItem);

          // email notification
          notifyGroupOfTask(context, workflowItem, mygroup, epa);
        } else {
          // no reviewers, skip ahead
          workflowItem.setState(WFSTATE_STEP1);
          archived = advance(context, workflowItem, null, true, false);
        }

        break;

      case WFSTATE_STEP1:

        // remove reviewers from tasklist
        // assign owner
        taskListItemService.deleteByWorkflowItem(context, workflowItem);
        workflowItem.setOwner(newowner);

        break;

      case WFSTATE_STEP2POOL:

        // clear owner
        // any approvers?
        // if so, add them to tasklist
        // if not, skip to next state
        workflowItem.setOwner(null);

        // get approvers (group 2)
        mygroup = collectionService.getWorkflowGroup(mycollection, 2);

        if ((mygroup != null) && !(groupService.isEmpty(mygroup))) {
          // get a list of all epeople in group (or any subgroups)
          List<EPerson> epa = groupService.allMembers(context, mygroup);

          // there were approvers, change the state
          //  timestamp, and add them to the list
          createTasks(context, workflowItem, epa);

          // email notification
          notifyGroupOfTask(context, workflowItem, mygroup, epa);
        } else {
          // no reviewers, skip ahead
          workflowItem.setState(WFSTATE_STEP2);
          archived = advance(context, workflowItem, null, true, false);
        }

        break;

      case WFSTATE_STEP2:

        // remove admins from tasklist
        // assign owner
        taskListItemService.deleteByWorkflowItem(context, workflowItem);
        workflowItem.setOwner(newowner);

        break;

      case WFSTATE_STEP3POOL:

        // any editors?
        // if so, add them to tasklist
        workflowItem.setOwner(null);
        mygroup = collectionService.getWorkflowGroup(mycollection, 3);

        if ((mygroup != null) && !(groupService.isEmpty(mygroup))) {
          // get a list of all epeople in group (or any subgroups)
          List<EPerson> epa = groupService.allMembers(context, mygroup);

          // there were editors, change the state
          //  timestamp, and add them to the list
          createTasks(context, workflowItem, epa);

          // email notification
          notifyGroupOfTask(context, workflowItem, mygroup, epa);
        } else {
          // no editors, skip ahead
          workflowItem.setState(WFSTATE_STEP3);
          archived = advance(context, workflowItem, null, true, false);
        }

        break;

      case WFSTATE_STEP3:

        // remove editors from tasklist
        // assign owner
        taskListItemService.deleteByWorkflowItem(context, workflowItem);
        workflowItem.setOwner(newowner);

        break;

      case WFSTATE_ARCHIVE:

        // put in archive in one transaction
        // remove workflow tasks
        taskListItemService.deleteByWorkflowItem(context, workflowItem);

        mycollection = workflowItem.getCollection();

        Item myitem = archive(context, workflowItem);

        // now email notification
        notifyOfArchive(context, myitem, mycollection);
        archived = true;

        break;
    }

    logWorkflowEvent(
        context,
        workflowItem.getItem(),
        workflowItem,
        context.getCurrentUser(),
        newstate,
        newowner,
        mycollection,
        oldState,
        mygroup);

    if (!archived) {
      workflowItemService.update(context, workflowItem);
    }

    return archived;
  }
Exemplo n.º 7
0
  public void addBody(Body body) throws SAXException, WingException, SQLException {
    // Get our parameters and state;
    UUID collectionID = UUID.fromString(parameters.getParameter("collectionID", null));
    Collection collection = collectionService.find(context, collectionID);

    List<Item> items = getMappedItems(collection);

    // DIVISION: browse-items
    Division div =
        body.addInteractiveDivision(
            "browse-items",
            contextPath + "/admin/mapper",
            Division.METHOD_GET,
            "primary administrative mapper");
    div.setHead(T_head1);

    if (authorizeService.authorizeActionBoolean(context, collection, Constants.REMOVE)) {
      Para actions = div.addPara();
      actions.addButton("submit_unmap").setValue(T_submit_unmap);
      actions.addButton("submit_return").setValue(T_submit_return);
    } else {
      Para actions = div.addPara();
      Button button = actions.addButton("submit_unmap");
      button.setValue(T_submit_unmap);
      button.setDisabled();
      actions.addButton("submit_return").setValue(T_submit_return);

      div.addPara().addHighlight("fade").addContent(T_no_remove);
    }

    Table table = div.addTable("browse-items-table", 1, 1);

    Row header = table.addRow(Row.ROLE_HEADER);
    header.addCellContent(T_column1);
    header.addCellContent(T_column2);
    header.addCellContent(T_column3);
    header.addCellContent(T_column4);

    for (Item item : items) {
      String itemID = String.valueOf(item.getID());
      Collection owningCollection = item.getOwningCollection();
      String owning = owningCollection.getName();
      String author = "unknown";
      List<MetadataValue> dcAuthors =
          itemService.getMetadata(
              item, MetadataSchema.DC_SCHEMA, "contributor", Item.ANY, Item.ANY);
      if (dcAuthors != null && dcAuthors.size() >= 1) {
        author = dcAuthors.get(0).getValue();
      }

      String title = "untitled";
      List<MetadataValue> dcTitles =
          itemService.getMetadata(item, MetadataSchema.DC_SCHEMA, "title", null, Item.ANY);
      if (dcTitles != null && dcTitles.size() >= 1) {
        title = dcTitles.get(0).getValue();
      }

      String url = contextPath + "/handle/" + item.getHandle();

      Row row = table.addRow();

      CheckBox select = row.addCell().addCheckBox("itemID");
      select.setLabel("Select");
      select.addOption(itemID);

      row.addCellContent(owning);
      row.addCell().addXref(url, author);
      row.addCell().addXref(url, title);
    }

    if (authorizeService.authorizeActionBoolean(context, collection, Constants.REMOVE)) {
      Para actions = div.addPara();
      actions.addButton("submit_unmap").setValue(T_submit_unmap);
      actions.addButton("submit_return").setValue(T_submit_return);
    } else {
      Para actions = div.addPara();
      Button button = actions.addButton("submit_unmap");
      button.setValue(T_submit_unmap);
      button.setDisabled();
      actions.addButton("submit_return").setValue(T_submit_return);

      div.addPara().addHighlight("fade").addContent(T_no_remove);
    }

    div.addHidden("administrative-continue").setValue(knot.getId());
  }
Exemplo n.º 8
0
  /**
   * Fills in the feed and entry-level metadata from DSpace objects.
   *
   * @param request request
   * @param context context
   * @param dso DSpaceObject
   * @param items array of objects
   * @param labels label map
   */
  public void populate(
      HttpServletRequest request,
      Context context,
      DSpaceObject dso,
      List<? extends DSpaceObject> items,
      Map<String, String> labels) {
    String logoURL = null;
    String objectURL = null;
    String defaultTitle = null;
    boolean podcastFeed = false;
    this.request = request;

    // dso is null for the whole site, or a search without scope
    if (dso == null) {
      defaultTitle = ConfigurationManager.getProperty("dspace.name");
      feed.setDescription(localize(labels, MSG_FEED_DESCRIPTION));
      objectURL = resolveURL(request, null);
      logoURL = ConfigurationManager.getProperty("webui.feed.logo.url");
    } else {
      Bitstream logo = null;
      if (dso.getType() == Constants.COLLECTION) {
        Collection col = (Collection) dso;
        defaultTitle = col.getName();
        feed.setDescription(collectionService.getMetadata(col, "short_description"));
        logo = col.getLogo();
        String cols = ConfigurationManager.getProperty("webui.feed.podcast.collections");
        if (cols != null && cols.length() > 1 && cols.contains(col.getHandle())) {
          podcastFeed = true;
        }
      } else if (dso.getType() == Constants.COMMUNITY) {
        Community comm = (Community) dso;
        defaultTitle = comm.getName();
        feed.setDescription(communityService.getMetadata(comm, "short_description"));
        logo = comm.getLogo();
        String comms = ConfigurationManager.getProperty("webui.feed.podcast.communities");
        if (comms != null && comms.length() > 1 && comms.contains(comm.getHandle())) {
          podcastFeed = true;
        }
      }
      objectURL = resolveURL(request, dso);
      if (logo != null) {
        logoURL = urlOfBitstream(request, logo);
      }
    }
    feed.setTitle(
        labels.containsKey(MSG_FEED_TITLE) ? localize(labels, MSG_FEED_TITLE) : defaultTitle);
    feed.setLink(objectURL);
    feed.setPublishedDate(new Date());
    feed.setUri(objectURL);

    // add logo if we found one:
    if (logoURL != null) {
      // we use the path to the logo for this, the logo itself cannot
      // be contained in the rdf. Not all RSS-viewers show this logo.
      SyndImage image = new SyndImageImpl();
      image.setLink(objectURL);
      if (StringUtils.isNotBlank(feed.getTitle())) {
        image.setTitle(feed.getTitle());
      } else {
        image.setTitle(localize(labels, MSG_LOGO_TITLE));
      }
      image.setUrl(logoURL);
      feed.setImage(image);
    }

    // add entries for items
    if (items != null) {
      List<SyndEntry> entries = new ArrayList<SyndEntry>();
      for (DSpaceObject itemDSO : items) {
        if (itemDSO.getType() != Constants.ITEM) {
          continue;
        }
        Item item = (Item) itemDSO;
        boolean hasDate = false;
        SyndEntry entry = new SyndEntryImpl();
        entries.add(entry);

        String entryURL = resolveURL(request, item);
        entry.setLink(entryURL);
        entry.setUri(entryURL);

        String title = getOneDC(item, titleField);
        entry.setTitle(title == null ? localize(labels, MSG_UNTITLED) : title);

        // "published" date -- should be dc.date.issued
        String pubDate = getOneDC(item, dateField);
        if (pubDate != null) {
          entry.setPublishedDate((new DCDate(pubDate)).toDate());
          hasDate = true;
        }
        // date of last change to Item
        entry.setUpdatedDate(item.getLastModified());

        StringBuffer db = new StringBuffer();
        for (String df : descriptionFields) {
          // Special Case: "(date)" in field name means render as date
          boolean isDate = df.indexOf("(date)") > 0;
          if (isDate) {
            df = df.replaceAll("\\(date\\)", "");
          }

          List<MetadataValue> dcv = itemService.getMetadataByMetadataString(item, df);
          if (dcv.size() > 0) {
            String fieldLabel = labels.get(MSG_METADATA + df);
            if (fieldLabel != null && fieldLabel.length() > 0) {
              db.append(fieldLabel).append(": ");
            }
            boolean first = true;
            for (MetadataValue v : dcv) {
              if (first) {
                first = false;
              } else {
                db.append("; ");
              }
              db.append(isDate ? new DCDate(v.getValue()).toString() : v.getValue());
            }
            db.append("\n");
          }
        }
        if (db.length() > 0) {
          SyndContent desc = new SyndContentImpl();
          desc.setType("text/plain");
          desc.setValue(db.toString());
          entry.setDescription(desc);
        }

        // This gets the authors into an ATOM feed
        List<MetadataValue> authors = itemService.getMetadataByMetadataString(item, authorField);
        if (authors.size() > 0) {
          List<SyndPerson> creators = new ArrayList<SyndPerson>();
          for (MetadataValue author : authors) {
            SyndPerson sp = new SyndPersonImpl();
            sp.setName(author.getValue());
            creators.add(sp);
          }
          entry.setAuthors(creators);
        }

        // only add DC module if any DC fields are configured
        if (dcCreatorField != null || dcDateField != null || dcDescriptionField != null) {
          DCModule dc = new DCModuleImpl();
          if (dcCreatorField != null) {
            List<MetadataValue> dcAuthors =
                itemService.getMetadataByMetadataString(item, dcCreatorField);
            if (dcAuthors.size() > 0) {
              List<String> creators = new ArrayList<String>();
              for (MetadataValue author : dcAuthors) {
                creators.add(author.getValue());
              }
              dc.setCreators(creators);
            }
          }
          if (dcDateField != null && !hasDate) {
            List<MetadataValue> v = itemService.getMetadataByMetadataString(item, dcDateField);
            if (v.size() > 0) {
              dc.setDate((new DCDate(v.get(0).getValue())).toDate());
            }
          }
          if (dcDescriptionField != null) {
            List<MetadataValue> v =
                itemService.getMetadataByMetadataString(item, dcDescriptionField);
            if (v.size() > 0) {
              StringBuffer descs = new StringBuffer();
              for (MetadataValue d : v) {
                if (descs.length() > 0) {
                  descs.append("\n\n");
                }
                descs.append(d.getValue());
              }
              dc.setDescription(descs.toString());
            }
          }
          entry.getModules().add(dc);
        }

        // iTunes Podcast Support - START
        if (podcastFeed) {
          // Add enclosure(s)
          List<SyndEnclosure> enclosures = new ArrayList();
          try {
            List<Bundle> bunds = itemService.getBundles(item, "ORIGINAL");
            if (bunds.get(0) != null) {
              List<Bitstream> bits = bunds.get(0).getBitstreams();
              for (Bitstream bit : bits) {
                String mime = bit.getFormat(context).getMIMEType();
                if (ArrayUtils.contains(podcastableMIMETypes, mime)) {
                  SyndEnclosure enc = new SyndEnclosureImpl();
                  enc.setType(bit.getFormat(context).getMIMEType());
                  enc.setLength(bit.getSize());
                  enc.setUrl(urlOfBitstream(request, bit));
                  enclosures.add(enc);
                } else {
                  continue;
                }
              }
            }
            // Also try to add an external value from dc.identifier.other
            // We are assuming that if this is set, then it is a media file
            List<MetadataValue> externalMedia =
                itemService.getMetadataByMetadataString(item, externalSourceField);
            if (externalMedia.size() > 0) {
              for (MetadataValue anExternalMedia : externalMedia) {
                SyndEnclosure enc = new SyndEnclosureImpl();
                enc.setType(
                    "audio/x-mpeg"); // We can't determine MIME of external file, so just picking
                                     // one.
                enc.setLength(1);
                enc.setUrl(anExternalMedia.getValue());
                enclosures.add(enc);
              }
            }

          } catch (Exception e) {
            System.out.println(e.getMessage());
          }
          entry.setEnclosures(enclosures);

          // Get iTunes specific fields: author, subtitle, summary, duration, keywords
          EntryInformation itunes = new EntryInformationImpl();

          String author = getOneDC(item, authorField);
          if (author != null && author.length() > 0) {
            itunes.setAuthor(author); // <itunes:author>
          }

          itunes.setSubtitle(
              title == null ? localize(labels, MSG_UNTITLED) : title); // <itunes:subtitle>

          if (db.length() > 0) {
            itunes.setSummary(db.toString()); // <itunes:summary>
          }

          String extent =
              getOneDC(
                  item,
                  "dc.format.extent"); // assumed that user will enter this field with length of
                                       // song in seconds
          if (extent != null && extent.length() > 0) {
            extent = extent.split(" ")[0];
            Integer duration = Integer.parseInt(extent);
            itunes.setDuration(new Duration(duration)); // <itunes:duration>
          }

          String subject = getOneDC(item, "dc.subject");
          if (subject != null && subject.length() > 0) {
            String[] subjects = new String[1];
            subjects[0] = subject;
            itunes.setKeywords(subjects); // <itunes:keywords>
          }

          entry.getModules().add(itunes);
        }
      }
      feed.setEntries(entries);
    }
  }