Java tutorial
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is Content Registry 2.0. * * The Initial Owner of the Original Code is European Environment * Agency. Portions created by Tieto Eesti are Copyright * (C) European Environment Agency. All Rights Reserved. * * Contributor(s): * Jaanus Heinlaid, Tieto Eesti */ package eionet.cr.web.action.factsheet; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.*; import javax.servlet.http.HttpServletRequest; import net.sourceforge.stripes.action.DefaultHandler; import net.sourceforge.stripes.action.ForwardResolution; import net.sourceforge.stripes.action.HandlesEvent; import net.sourceforge.stripes.action.RedirectResolution; import net.sourceforge.stripes.action.Resolution; import net.sourceforge.stripes.action.StreamingResolution; import net.sourceforge.stripes.action.UrlBinding; import net.sourceforge.stripes.validation.SimpleError; import net.sourceforge.stripes.validation.ValidationMethod; import org.apache.commons.beanutils.BeanComparator; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; import org.apache.log4j.Logger; import eionet.cr.common.Predicates; import eionet.cr.common.Subjects; import eionet.cr.config.GeneralConfig; import eionet.cr.dao.CompiledDatasetDAO; import eionet.cr.dao.DAOException; import eionet.cr.dao.DAOFactory; import eionet.cr.dao.HarvestSourceDAO; import eionet.cr.dao.HelperDAO; import eionet.cr.dao.ScoreboardSparqlDAO; import eionet.cr.dao.SpoBinaryDAO; import eionet.cr.dao.virtuoso.PredicateObjectsReader; import eionet.cr.dataset.CurrentLoadedDatasets; import eionet.cr.dto.DatasetDTO; import eionet.cr.dto.FactsheetDTO; import eionet.cr.dto.HarvestSourceDTO; import eionet.cr.dto.ObjectDTO; import eionet.cr.dto.SubjectDTO; import eionet.cr.dto.TripleDTO; import eionet.cr.harvest.CurrentHarvests; import eionet.cr.harvest.HarvestException; import eionet.cr.harvest.OnDemandHarvester; import eionet.cr.harvest.scheduled.UrgentHarvestQueue; import eionet.cr.harvest.util.CsvImportUtil; import eionet.cr.util.Pair; import eionet.cr.util.URLUtil; import eionet.cr.util.Util; import eionet.cr.web.action.AbstractActionBean; import eionet.cr.web.action.BrowseCodelistsActionBean; import eionet.cr.web.action.source.ViewSourceActionBean; import eionet.cr.web.util.ApplicationCache; import eionet.cr.web.util.HTMLSelectOption; import eionet.cr.web.util.tabs.FactsheetTabMenuHelper; import eionet.cr.web.util.tabs.TabElement; import eionet.cr.web.util.tabs.TabId; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; /** * Factsheet. * * @author <a href="mailto:jaanus.heinlaid@tietoenator.com">Jaanus Heinlaid</a> * */ @UrlBinding("/factsheet.action") public class FactsheetActionBean extends AbstractActionBean { /** Substring by which URIs of codelists and their members are checked. */ private static final String CODELIST_SUBSTRING = "/codelist/"; /** Name of the resource file containing the list of fully editable types. */ private static final String FULLY_EDITABLE_TYPES_FILE_NAME = "fully-editable-types.txt"; /** */ private static final String DATASET_EDITABLE_PROPERTIES_FILE_NAME = "dataset-editable-properties.json"; /** */ private static final Logger LOGGER = Logger.getLogger(FactsheetActionBean.class); /** */ public static final String PAGE_PARAM_PREFIX = "page"; /** */ private static final String ADDBL_PROPS_SESSION_ATTR_PREFIX = "addibleProperties_"; /** */ private static final List<HTMLSelectOption> DATACUBE_DATASET_ADDBL_PROPS = createDataCubeDatasetAddibleProperties(); /** */ private static final List<HTMLSelectOption> COMMON_ADDBL_PROPS = createCommonAddibleProperties(); /** */ private static final Set<String> EDITABLE_TYPES = createEditableTypes(); /** URI by which the factsheet has been requested. */ private String uri; /** URI hash by which the factsheet has been requested. Ignored when factsheet requested by URI. */ private long uriHash; /** The subject data object found by the requestd URI or URI hash. */ private FactsheetDTO subject; /** Used in factsheet edit mode only, where it indicates if the subject is anonymous. */ private boolean anonymous; /** */ private String propertyUri; /** */ private String propertyValue; /** List of identifiers of property-value rows submitted from factsheet edit form. */ private List<String> rowId; /** True if the session bears a user and it happens to be an administrator. Otherwise false. */ private boolean adminLoggedIn; /** True if the found subject is a bookmark of the logged-in user. In all other cases false. */ private Boolean subjectIsUserBookmark; /** True if the found subject has downloadable content in filestore. */ private Boolean subjectDownloadable; /** True, if URI is harvest source. */ private boolean uriIsHarvestSource; /** True, if URI is a graph. */ private boolean uriIsGraph; /** True, if URI is local folder. */ private boolean uriIsFolder; /** */ private String bookmarkLabel; /** */ private Map<String, Integer> predicatePageNumbers; private Map<String, Integer> predicatePageCounts; /** */ private List<TabElement> tabs; /** */ private Boolean subjectIsType = null; /** */ private String predicateUri; private String objectMD5; private String graphUri; /** */ private List<DatasetDTO> userCompiledDatasets; /** */ private HarvestSourceDTO harvestSourceDTO; /** */ private SubjectDTO fullSubjectDTO; /** */ private Boolean isAllEditable = null; /** * * @return Resolution * @throws DAOException * if query fails */ @DefaultHandler public Resolution view() throws DAOException { if (isNoCriteria()) { addCautionMessage("No request criteria specified!"); } else { HelperDAO helperDAO = DAOFactory.get().getDao(HelperDAO.class); setAdminLoggedIn(getUser() != null && getUser().isAdministrator()); subject = helperDAO.getFactsheet(uri, null, getPredicatePageNumbers()); if (subject != null) { fullSubjectDTO = helperDAO.getSubject(uri); } FactsheetTabMenuHelper tabsHelper = new FactsheetTabMenuHelper(uri, fullSubjectDTO, factory.getDao(HarvestSourceDAO.class)); tabs = tabsHelper.getTabs(TabId.RESOURCE_PROPERTIES); uriIsHarvestSource = tabsHelper.isUriIsHarvestSource(); uriIsGraph = tabsHelper.isUriIsGraph(); uriIsFolder = tabsHelper.isUriFolder(); harvestSourceDTO = tabsHelper.getHarvestSourceDTO(); } return new ForwardResolution("/pages/factsheet/factsheet.jsp"); } /** * Handle for ajax harvesting. * * @return Resolution */ public Resolution harvestAjax() { String message; try { message = harvestNow().getRight(); } catch (Exception ignored) { logger.error("error while scheduling ajax harvest", ignored); message = "Error occured, more info can be obtained in application logs"; } return new StreamingResolution("text/html", message); } /** * Schedules a harvest for resource. * * @return view resolution * @throws HarvestException * if harvesting fails * @throws DAOException * if query fails */ public Resolution harvest() throws HarvestException, DAOException { HelperDAO helperDAO = DAOFactory.get().getDao(HelperDAO.class); SubjectDTO subjectDto = helperDAO.getSubject(uri); if (subjectDto != null && CsvImportUtil.isSourceTableFile(subjectDto)) { // Harvest table file try { // harvestTableFile(); List<String> warnings = CsvImportUtil.harvestTableFile(subjectDto, uri, getUserName()); for (String msg : warnings) { addWarningMessage(msg); } addSystemMessage("Source successfully harvested"); } catch (Exception e) { logger.error("Failed to harvest table file", e); addWarningMessage("Failed to harvest table file: " + e.getMessage()); } } else { // Harvest other source Pair<Boolean, String> message = harvestNow(); if (message.getLeft()) { addWarningMessage(message.getRight()); } else { addSystemMessage(message.getRight()); } } return new RedirectResolution(this.getClass(), "view").addParameter("uri", uri); } /** * helper method to eliminate code duplication. * * @return Pair<Boolean, String> feedback messages * @throws HarvestException * if harvesting fails * @throws DAOException * if query fails */ private Pair<Boolean, String> harvestNow() throws HarvestException, DAOException { String message = null; if (isUserLoggedIn()) { if (!StringUtils.isBlank(uri) && URLUtil.isURL(uri)) { /* add this url into HARVEST_SOURCE table */ HarvestSourceDAO dao = factory.getDao(HarvestSourceDAO.class); HarvestSourceDTO dto = new HarvestSourceDTO(); dto.setUrl(StringUtils.substringBefore(uri, "#")); dto.setEmails(""); dto.setIntervalMinutes( Integer.valueOf(GeneralConfig.getProperty(GeneralConfig.HARVESTER_REFERRALS_INTERVAL, String.valueOf(HarvestSourceDTO.DEFAULT_REFERRALS_INTERVAL)))); dto.setPrioritySource(false); dto.setOwner(null); dao.addSourceIgnoreDuplicate(dto); /* issue an instant harvest of this url */ OnDemandHarvester.Resolution resolution = OnDemandHarvester.harvest(dto.getUrl(), getUserName()); /* give feedback to the user */ if (resolution.equals(OnDemandHarvester.Resolution.ALREADY_HARVESTING)) { message = "The resource is currently being harvested by another user or background harvester!"; } else if (resolution.equals(OnDemandHarvester.Resolution.UNCOMPLETE)) { message = "The harvest hasn't finished yet, but continues in the background!"; } else if (resolution.equals(OnDemandHarvester.Resolution.COMPLETE)) { message = "The harvest has been completed!"; } else if (resolution.equals(OnDemandHarvester.Resolution.SOURCE_UNAVAILABLE)) { message = "The resource was not available!"; } else if (resolution.equals(OnDemandHarvester.Resolution.NO_STRUCTURED_DATA)) { message = "The resource contained no RDF data!"; // else if (resolution.equals(InstantHarvester.Resolution.RECENTLY_HARVESTED)) // message = "Source redirects to another source that has recently been harvested! Will not harvest."; } else { message = "No feedback given from harvest!"; } } return new Pair<Boolean, String>(false, message); } else { return new Pair<Boolean, String>(true, getBundle().getString("not.logged.in")); } } /** * * @return Resolution * @throws DAOException * if query fails if query fails */ public Resolution edit() throws DAOException { return view(); } /** * * @return Resolution * @throws DAOException * if query fails if query fails */ public Resolution addbookmark() throws DAOException { if (isUserLoggedIn()) { DAOFactory.get().getDao(HelperDAO.class).addUserBookmark(getUser(), getUrl(), bookmarkLabel); addSystemMessage("Succesfully bookmarked this source."); } else { addSystemMessage("Only logged in users can bookmark sources."); } return view(); } /** * * @return Resolution * @throws DAOException * if query fails */ public Resolution removebookmark() throws DAOException { if (isUserLoggedIn()) { DAOFactory.get().getDao(HelperDAO.class).deleteUserBookmark(getUser(), getUrl()); addSystemMessage("Succesfully removed this source from bookmarks."); } else { addSystemMessage("Only logged in users can remove bookmarks."); } return view(); } /** * * @return Resolution * @throws DAOException * if query fails if query fails */ public Resolution save() throws DAOException { // Get the distinct types that this subject currently has in repository. // FIXME: the resulting list should also probably be complemented with any new types coming from the current save! SubjectDTO currSubj = DAOFactory.get().getDao(HelperDAO.class).getSubject(uri); Collection<String> types = currSubj == null ? new HashSet<String>() : currSubj.getObjectValues(Predicates.RDF_TYPE); // Prepare blank subject DTO for collecting the triples about to be saved. SubjectDTO subjectDTO = new SubjectDTO(uri, anonymous); // URI of source of saved triples depends on whether we're saving a DataCube dataset or not. String sourceUri = types.contains(Subjects.DATACUBE_DATA_SET) ? uri : getUser().getRegistrationsUri(); // URI of property (i.e. predicate) that is saved. Special case if it's cr:tag. if (propertyUri.equals(Predicates.CR_TAG)) { List<String> tags = Util.splitStringBySpacesExpectBetweenQuotes(propertyValue); for (String tag : tags) { ObjectDTO objectDTO = new ObjectDTO(tag, true); objectDTO.setSourceUri(sourceUri); subjectDTO.addObject(propertyUri, objectDTO); } } else { // If saved property is not cr:tag. // Add saved predicate-object pair into subject DTO. boolean isLiteral = !URLUtil.isURL(propertyValue); ObjectDTO objectDTO = new ObjectDTO(propertyValue, isLiteral); objectDTO.setSourceUri(sourceUri); subjectDTO.addObject(propertyUri, objectDTO); } // Add saved triples into repository. HelperDAO helperDao = factory.getDao(HelperDAO.class); helperDao.addTriples(subjectDTO); helperDao.updateUserHistory(getUser(), uri); // Updated dcterms:modified. try { updateDctModified(currSubj, types, sourceUri); } catch (DAOException e) { LOGGER.error("Failed to update dcterms:modified", e); } // Since user registrations URI was used as triple source, add it to HARVEST_SOURCE too // (but set interval minutes to 0, to avoid it being background-harvested) if (sourceUri != null && sourceUri.equals(getUser().getRegistrationsUri())) { DAOFactory.get().getDao(HarvestSourceDAO.class) .addSourceIgnoreDuplicate(HarvestSourceDTO.create(sourceUri, true, 0, getUser().getUserName())); } return new RedirectResolution(this.getClass(), "edit").addParameter("uri", uri); } /** * Helper method for updating dcterms:modified if the given subject has been updated (i.e. triples added or deleted). * * @param currSubj The subject's DTO as it is currently in the repository. * @param types The subject's RDF types. * @param sourceUri The graph URI where the dcterms:modified should be updated. * @throws DAOException if any sort of DB error happens */ private void updateDctModified(SubjectDTO currSubj, Collection<String> types, String sourceUri) throws DAOException { if (currSubj == null || StringUtils.isBlank(sourceUri)) { return; } String dctModifiedSubjectUri = null; if (types.contains(Subjects.DATACUBE_DATA_SET)) { dctModifiedSubjectUri = uri; } else if (types.contains(Subjects.DATACUBE_OBSERVATION)) { if (currSubj != null) { List<String> datasetUris = currSubj.getObjectValues(Predicates.DATACUBE_DATA_SET); if (datasetUris != null && !datasetUris.isEmpty()) { dctModifiedSubjectUri = datasetUris.iterator().next(); } } } else if (uri.contains(CODELIST_SUBSTRING)) { String tail = StringUtils.substringAfter(uri, CODELIST_SUBSTRING); int i = tail.indexOf('/'); if (i < 0) { dctModifiedSubjectUri = uri; } else { dctModifiedSubjectUri = StringUtils.substringBefore(uri, CODELIST_SUBSTRING) + CODELIST_SUBSTRING + tail.substring(0, i); } } if (StringUtils.isNotBlank(dctModifiedSubjectUri)) { DAOFactory.get().getDao(ScoreboardSparqlDAO.class).updateDcTermsModified(dctModifiedSubjectUri, new Date(), sourceUri); } } /** * * @return Resolution * @throws DAOException * if query fails */ public Resolution delete() throws DAOException { if (rowId != null && !rowId.isEmpty()) { ArrayList<TripleDTO> triples = new ArrayList<TripleDTO>(); for (String row : rowId) { int i = row.indexOf("_"); if (i <= 0 || i == (row.length() - 1)) { throw new IllegalArgumentException("Illegal rowId: " + row); } String predicateHash = row.substring(0, i); String predicate = getContext().getRequestParameter("pred_".concat(predicateHash)); String objectHash = row.substring(i + 1); String objectValue = getContext().getRequest().getParameter("obj_".concat(objectHash)); String sourceUri = getContext().getRequest().getParameter("source_".concat(objectHash)); TripleDTO triple = new TripleDTO(uri, predicate, objectValue == null ? null : objectValue.replace("\r", "")); // FIXME - find a better way to determine if the object is literal or not, URIs may be literals also triple.setLiteralObject(!URLUtil.isURL(objectValue)); triple.setSourceUri(sourceUri); triples.add(triple); } HelperDAO helperDao = factory.getDao(HelperDAO.class); helperDao.deleteTriples(triples); helperDao.updateUserHistory(getUser(), uri); // Update dcterms:modified. // FIXME: the resulting types list should also probably be complemented with any new types coming from the current save! SubjectDTO currSubj = DAOFactory.get().getDao(HelperDAO.class).getSubject(uri); Collection<String> types = currSubj == null ? new HashSet<String>() : currSubj.getObjectValues(Predicates.RDF_TYPE); String sourceUri = types.contains(Subjects.DATACUBE_DATA_SET) ? uri : getUser().getRegistrationsUri(); try { updateDctModified(currSubj, types, sourceUri); } catch (DAOException e) { LOGGER.error("Failed to update dcterms:modified", e); } } else { addWarningMessage("You selected no triples to delete!"); } return new RedirectResolution(this.getClass(), "edit").addParameter("uri", uri); } /** * Validates if user is logged on and if event property is not empty. */ @ValidationMethod(on = { "save", "delete", "edit", "harvest" }) public void validateUserKnown() { if (getUser() == null) { addWarningMessage("Operation not allowed for anonymous users"); } else if (getContext().getEventName().equals("save") && StringUtils.isBlank(propertyValue)) { addGlobalValidationError(new SimpleError("Property value must not be blank")); } } /** * @return the resourceUri */ public String getUri() { return uri; } /** * @param resourceUri * the resourceUri to set */ public void setUri(final String resourceUri) { this.uri = resourceUri; } /** * @return the resource */ public FactsheetDTO getSubject() { return subject; } /** * * @return * @throws DAOException */ @SuppressWarnings("unchecked") public List<HTMLSelectOption> getAddibleProperties() throws DAOException { String sessionAttrName = ADDBL_PROPS_SESSION_ATTR_PREFIX + uri; List<HTMLSelectOption> result = (List<HTMLSelectOption>) getContext().getSessionAttribute(sessionAttrName); if (CollectionUtils.isEmpty(result)) { // Get the subject's RDF types. Collection<String> rdfTypes = fullSubjectDTO == null ? null : fullSubjectDTO.getObjectValues(Predicates.RDF_TYPE); // Special case for DataCube datasets. if (rdfTypes.contains(Subjects.DATACUBE_DATA_SET)) { getContext().setSessionAttribute(sessionAttrName, DATACUBE_DATASET_ADDBL_PROPS); return DATACUBE_DATASET_ADDBL_PROPS; } // Get addible properties from the repository. HelperDAO dao = DAOFactory.get().getDao(HelperDAO.class); Map<String, HTMLSelectOption> options = dao.getAddibleProperties(uri, rdfTypes); // Add some hard-coded addable properties. for (HTMLSelectOption htmlSelectOption : COMMON_ADDBL_PROPS) { options.put(htmlSelectOption.getValue(), htmlSelectOption); } result = new ArrayList<HTMLSelectOption>(); result.addAll(options.values()); Collections.sort(result, new BeanComparator("label")); getContext().setSessionAttribute(sessionAttrName, result); } return result; } /** * @param anonymous * the anonymous to set */ public void setAnonymous(final boolean anonymous) { this.anonymous = anonymous; } /** * @param propertyUri * the propertyUri to set */ public void setPropertyUri(final String propertyUri) { this.propertyUri = propertyUri; } /** * @param propertyValue * the propertyValue to set */ public void setPropertyValue(final String propertyValue) { this.propertyValue = propertyValue; } /** * @param rowId * the rowId to set */ public void setRowId(final List<String> rowId) { this.rowId = rowId; } /** * @return the noCriteria */ public boolean isNoCriteria() { return StringUtils.isBlank(uri); } /** * @return the uriHash */ public long getUriHash() { return uriHash; } /** * @param uriHash * the uriHash to set */ public void setUriHash(final long uriHash) { this.uriHash = uriHash; } /** * * @return String */ public String getUrl() { return uri != null && URLUtil.isURL(uri) ? uri : null; } /** * True if admin is logged in. * * @return boolean */ public boolean isAdminLoggedIn() { return adminLoggedIn; } /** * Setter of admin logged in property. * * @param adminLoggedIn * boolean */ public void setAdminLoggedIn(final boolean adminLoggedIn) { this.adminLoggedIn = adminLoggedIn; } /** * * @return boolean * @throws DAOException * if query fails if query fails */ public boolean getSubjectIsUserBookmark() throws DAOException { if (!isUserLoggedIn()) { return false; } if (subjectIsUserBookmark == null) { subjectIsUserBookmark = Boolean .valueOf(factory.getDao(HelperDAO.class).isSubjectUserBookmark(getUser(), uri)); } return subjectIsUserBookmark.booleanValue(); } /** * @return the subjectDownloadable * @throws DAOException */ public boolean isSubjectDownloadable() throws DAOException { if (subjectDownloadable == null) { subjectDownloadable = Boolean.valueOf(DAOFactory.get().getDao(SpoBinaryDAO.class).exists(uri)); } return subjectDownloadable.booleanValue(); } /** * * @return boolean */ public boolean isCurrentlyHarvested() { return uri == null ? false : (CurrentHarvests.contains(uri) || UrgentHarvestQueue.isInQueue(uri) || CurrentLoadedDatasets.contains(uri)); } /** * * @return boolean */ public boolean isCompiledDataset() { boolean ret = false; if (subject.getObject(Predicates.RDF_TYPE) != null) { ret = Subjects.CR_COMPILED_DATASET.equals(subject.getObject(Predicates.RDF_TYPE).getValue()); } return ret; } /** * * @return Resolution * @throws DAOException */ public Resolution showOnMap() throws DAOException { HelperDAO helperDAO = DAOFactory.get().getDao(HelperDAO.class); subject = helperDAO.getFactsheet(uri, null, null); if (subject != null) { fullSubjectDTO = helperDAO.getSubject(uri); } FactsheetTabMenuHelper helper = new FactsheetTabMenuHelper(uri, fullSubjectDTO, factory.getDao(HarvestSourceDAO.class)); tabs = helper.getTabs(TabId.SHOW_ON_MAP); return new ForwardResolution("/pages/factsheet/map.jsp"); } public boolean isUriIsHarvestSource() { return uriIsHarvestSource; } /** * * @return */ public String getBookmarkLabel() { return bookmarkLabel; } /** * * @param bookmarkLabel */ public void setBookmarkLabel(String bookmarkLabel) { this.bookmarkLabel = bookmarkLabel; } /** * @return the predicatePages */ public Map<String, Integer> getPredicatePageNumbers() { if (predicatePageNumbers == null) { predicatePageNumbers = new HashMap<String, Integer>(); HttpServletRequest request = getContext().getRequest(); Map<String, String[]> paramsMap = request.getParameterMap(); if (paramsMap != null && !paramsMap.isEmpty()) { for (Map.Entry<String, String[]> entry : paramsMap.entrySet()) { String paramName = entry.getKey(); if (isPredicatePageParam(paramName)) { int pageNumber = NumberUtils.toInt(paramName.substring(PAGE_PARAM_PREFIX.length())); if (pageNumber > 0) { String[] predicateUris = entry.getValue(); if (predicateUris != null) { for (String predUri : predicateUris) { predicatePageNumbers.put(predUri, pageNumber); } } } } } } } return predicatePageNumbers; } /** * * @param paramName * @return */ public boolean isPredicatePageParam(String paramName) { if (paramName.startsWith(PAGE_PARAM_PREFIX) && paramName.length() > PAGE_PARAM_PREFIX.length()) { return StringUtils.isNumeric(paramName.substring(PAGE_PARAM_PREFIX.length())); } else { return false; } } /** * * @return */ public int getPredicatePageSize() { return PredicateObjectsReader.PREDICATE_PAGE_SIZE; } /** * * @return */ public List<TabElement> getTabs() { return tabs; } /** * * @return */ public boolean getSubjectIsType() { if (subjectIsType == null) { List<String> typeUris = ApplicationCache.getTypeUris(); subjectIsType = Boolean.valueOf(typeUris.contains(this.uri)); } return subjectIsType; } /** * * @return */ @HandlesEvent("openPredObjValue") public Resolution openPredObjValue() { logger.trace("Retrieving object value for MD5 " + objectMD5 + " of predicate " + predicateUri); String value = DAOFactory.get().getDao(HelperDAO.class).getLiteralObjectValue(uri, predicateUri, objectMD5, graphUri); if (StringUtils.isBlank(value)) { value = "Found no value!"; } else { value = StringEscapeUtils.escapeXml(value); } return new StreamingResolution("text/html", value); } /** * @param predicateUri * the predicateUri to set */ public void setPredicateUri(String predicateUri) { this.predicateUri = predicateUri; } /** * @param objectMD5 * the objectMD5 to set */ public void setObjectMD5(String objectMD5) { this.objectMD5 = objectMD5; } /** * @param graphUri * the graphUri to set */ public void setGraphUri(String graphUri) { this.graphUri = graphUri; } /** * * @return */ public List<DatasetDTO> getUserCompiledDatasets() { if (userCompiledDatasets == null && !StringUtils.isBlank(uri)) { try { CompiledDatasetDAO dao = DAOFactory.get().getDao(CompiledDatasetDAO.class); userCompiledDatasets = dao.getCompiledDatasets(getUser().getHomeUri(), uri); } catch (DAOException e) { e.printStackTrace(); } } return userCompiledDatasets; } /** * * @param userCompiledDatasets */ public void setUserCompiledDatasets(List<DatasetDTO> userCompiledDatasets) { this.userCompiledDatasets = userCompiledDatasets; } /** * * @return */ public Class getViewSourceActionBeanClass() { return ViewSourceActionBean.class; } /** * * @return */ public boolean isUriIsFolder() { return uriIsFolder; } /** * * @param uriIsFolder */ public void setUriIsFolder(boolean uriIsFolder) { this.uriIsFolder = uriIsFolder; } /** * @return the harvestSourceDTO */ public HarvestSourceDTO getHarvestSourceDTO() { return harvestSourceDTO; } /** * @return the uriIsGraph */ public boolean isUriIsGraph() { return uriIsGraph; } /** * * @return */ public boolean isDataCubeDataset() { if (fullSubjectDTO == null) { return false; } Collection<String> types = fullSubjectDTO.getObjectValues(Predicates.RDF_TYPE); return types != null && types.contains(Subjects.DATACUBE_DATA_SET); } /** * * @return */ public boolean isScoreboardCodelist() { if (fullSubjectDTO == null) { return false; } Collection<String> types = fullSubjectDTO.getObjectValues(Predicates.RDF_TYPE); if (types != null && types.contains(Subjects.SKOS_CONCEPT_SCHEME)) { return fullSubjectDTO.getUri().startsWith(BrowseCodelistsActionBean.CODELISTS_PREFIX); } else { return false; } } /** * @return */ public boolean isAllEditable() { if (isAllEditable == null) { isAllEditable = Boolean.FALSE; Collection<String> types = fullSubjectDTO == null ? null : fullSubjectDTO.getObjectValues(Predicates.RDF_TYPE); if (types != null && !types.isEmpty()) { if (EDITABLE_TYPES != null && !EDITABLE_TYPES.isEmpty()) { for (String type : types) { if (EDITABLE_TYPES.contains(type)) { isAllEditable = Boolean.TRUE; break; } } } } } return isAllEditable.booleanValue(); } /** * Handler for the "Change dataset status" event. Relevant only if the underlying resource is a DataCube dataset. * * @return */ public Resolution changeDatasetStatus() { String newStatus = getContext().getRequestParameter("datasetStatus"); if (StringUtils.isBlank(newStatus)) { addWarningMessage("The new dataset status must be specified!"); } else { List<String> allowableValues = Arrays.asList("http://purl.org/adms/status/Completed", "http://purl.org/adms/status/UnderDevelopment", "http://purl.org/adms/status/Deprecated", "http://purl.org/adms/status/Withdrawn"); if (!allowableValues.contains(newStatus)) { addWarningMessage("Unrecognized dataset status value: " + newStatus); } else { try { DAOFactory.get().getDao(ScoreboardSparqlDAO.class).changeDatasetStatus(uri, newStatus); addSystemMessage("Datatset status successfully updated!"); } catch (DAOException e) { LOGGER.error("Technical error when attemptring to change the status of " + uri, e); addWarningMessage("A technical error occurred when trying to change the dataset status: " + e.getMessage()); } } } return new RedirectResolution(getClass()).addParameter("uri", uri); } /** * * @return */ private static List<HTMLSelectOption> createDataCubeDatasetAddibleProperties() { ArrayList<HTMLSelectOption> resultList = new ArrayList<>(); InputStream inputStream = null; JSONParser jsonParser = new JSONParser(); try { inputStream = FactsheetActionBean.class.getClassLoader() .getResourceAsStream(DATASET_EDITABLE_PROPERTIES_FILE_NAME); JSONArray objects = (JSONArray) jsonParser.parse(new InputStreamReader(inputStream)); if (objects != null) { for (Object object : objects) { JSONObject jsonObject = (JSONObject) object; resultList.add(new HTMLSelectOption((String) jsonObject.get("uri"), (String) jsonObject.get("label"), (String) jsonObject.get("hint"))); } } } catch (IOException e) { LOGGER.error( "IOException when finding/reading this resource file: " + DATASET_EDITABLE_PROPERTIES_FILE_NAME, e); } catch (ParseException e) { LOGGER.error("Failed parsing JSON from this resource file: " + DATASET_EDITABLE_PROPERTIES_FILE_NAME, e); } finally { IOUtils.closeQuietly(inputStream); } Collections.sort(resultList, new Comparator<HTMLSelectOption>() { @Override public int compare(HTMLSelectOption o1, HTMLSelectOption o2) { return o1.getLabel().compareTo(o2.getLabel()); } }); return resultList; } /** * @return */ private static List<HTMLSelectOption> createCommonAddibleProperties() { ArrayList<HTMLSelectOption> result = new ArrayList<HTMLSelectOption>(); HTMLSelectOption option = new HTMLSelectOption(Predicates.RDFS_LABEL, "Title"); option.setTitle("RDF Schema label, i.e. a human-readable name that applications " + "can use for displaying in user interfaces. May be any free text."); result.add(option); option = new HTMLSelectOption(Predicates.CR_TAG, "Tag"); result.add(option); option = new HTMLSelectOption(Predicates.RDFS_COMMENT, "Comment"); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_TITLE, "Title"); option.setTitle("DublinCore title. May be any free text."); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_ABSTRACT, "Abstract"); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_CONTRIBUTOR, "Contributor"); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_CREATOR, "Creator"); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_DATE, "Date"); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_DESCRIPTION, "Description"); option.setTitle( "DublinCore description, i.e. a human-readable description of the resource. May be any free text."); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_FORMAT, "Format"); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_IDENTIFIER, "Identifier"); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_LANGUAGE, "Language"); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_LICENSE, "Licenese"); option.setTitle("A legal document giving official permission to do something with the resource. " + "Usually a URL pointing to the document."); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_MODIFIED, "Modified"); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_PUBLISHER, "Publisher"); option.setTitle( "DublinCore publisher, i.e. a person, an organization, or a service that is the resource's publisher. " + "May be any free text, but it is advised to use URLs."); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_RIGHTS, "Rights"); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_SOURCE, "Source"); result.add(option); option = new HTMLSelectOption(Predicates.DCTERMS_SUBJECT, "Subject"); result.add(option); option = new HTMLSelectOption(Predicates.RDFS_DOMAIN, "rdfs:domain"); result.add(option); result.add(HTMLSelectOption.createFromUri(Predicates.SKOS_ALT_LABEL, "altLabel")); result.add(HTMLSelectOption.createFromUri(Predicates.SKOS_PREF_LABEL, "prefLabel")); result.add(HTMLSelectOption.createFromUri(Predicates.SKOS_NOTATION, "notation")); result.add(HTMLSelectOption.createFromUri(Predicates.SKOS_NOTE, "notes")); result.add(HTMLSelectOption.createFromUri(Predicates.SKOS_DEFINITION, "definition")); result.add(HTMLSelectOption.createFromUri(Predicates.SKOS_HAS_TOP_CONCEPT, "hasTopConcept")); return result; } /** * * @return */ private static Set<String> createEditableTypes() { LinkedHashSet<String> result = new LinkedHashSet<String>(); InputStream inputStream = null; try { inputStream = FactsheetActionBean.class.getClassLoader() .getResourceAsStream(FULLY_EDITABLE_TYPES_FILE_NAME); List<String> lines = IOUtils.readLines(inputStream, "UTF-8"); for (String line : lines) { result.add(line.trim()); } } catch (IOException e) { LOGGER.error("Failed reading lines from " + FULLY_EDITABLE_TYPES_FILE_NAME, e); } finally { IOUtils.closeQuietly(inputStream); } LOGGER.debug("Found these fully editable types: " + result); return result; } }