Ejemplo n.º 1
0
 /**
  * Returns a hash code for the given object.
  *
  * @see java.lang.Object#hashCode()
  * @param o the object to create a hash for
  * @return the hash code of the object
  */
 public static int hashCode(PropertyDocument o) {
   int result;
   result = hashCodeForTermedDocument(o);
   result = prime * result + o.getStatementGroups().hashCode();
   result = prime * result + o.getDatatype().hashCode();
   return result;
 }
  private PropertyIdValue createOrGetWikidataProperty(
      final String propertyIdentifier, final String propertyValueDataType) {

    return gdmPropertyURIWikidataPropertyMap.computeIfAbsent(
        propertyIdentifier,
        propertyIdentifier1 -> {
          final List<MonolingualTextValue> labels = generateLabels(propertyIdentifier1);
          final List<MonolingualTextValue> descriptions = generateLabels(propertyIdentifier1);
          final List<MonolingualTextValue> aliases = new ArrayList<>();

          // add datatype - e.g. all literals are strings (DatatypeIdValue#DT_STRING) and all
          // resources are items (DatatypeIdValue#DT_ITEM)
          final DatatypeIdValue datatypeIdValue =
              Datamodel.makeDatatypeIdValue(propertyValueDataType);

          // note: list of descriptions cannot be null
          // note: list of aliases cannot be null
          final PropertyDocument wikidataProperty =
              Datamodel.makePropertyDocument(null, labels, descriptions, aliases, datatypeIdValue);

          // create Property at Wikibase (to have a generated Property identifier)
          try {

            final Observable<Response> createEntityResponse =
                wikibaseAPIClient.createEntity(
                    wikidataProperty, WikibaseAPIClient.WIKIBASE_API_ENTITY_TYPE_PROPERTY);

            // handle duplicates, i.e., one can only create uniquely labelled properties in
            // wikibase, otherwise "wikibase-validator-label-conflict" will be thrown
            final JsonNode entityOrErrorJSON =
                processEditEntityResponse(
                    propertyIdentifier1,
                    createEntityResponse,
                    WikibaseAPIClient.WIKIBASE_API_ENTITY_TYPE_PROPERTY);

            final JsonNode errorNode = entityOrErrorJSON.get(MEDIAWIKI_ERROR_IDENTIFIER);

            if (errorNode == null) {

              // response JSON should be an entity

              final PropertyDocument propertyDocument =
                  MAPPER.treeToValue(entityOrErrorJSON, JacksonPropertyDocument.class);

              if (propertyDocument == null) {

                final String message =
                    String.format(
                        "could not create new property for '%s'; could not deserialize response body",
                        propertyIdentifier1);

                LOG.error(message);

                throw new WikidataImporterException(message);
              }

              final PropertyIdValue responsePropertyId = propertyDocument.getPropertyId();

              if (responsePropertyId == null) {

                final String message =
                    String.format(
                        "could not create new property for '%s'; response property id is not available",
                        propertyIdentifier1);

                LOG.error(message);

                throw new WikidataImporterException(message);
              }

              return responsePropertyId;
            }

            // TODO: refactoring following code and that one of item creation duplicate handling
            // into separate method

            // an error occurred

            final JsonNode errorCodeJSON = errorNode.get(MEDIAWIKI_CODE_IDENTIFIER);

            if (errorCodeJSON == null) {

              final String message =
                  String.format(
                      "could not create new property for '%s'; an unknown error ('%s') occurred",
                      propertyIdentifier1, MAPPER.writeValueAsString(errorNode));

              throw new WikidataImporterException(message);
            }

            final String errorCode = errorCodeJSON.asText();

            if (!MEDIAWIKI_FAILED_SAVE_ERROR_CODE.equals(errorCode)) {

              final String message =
                  String.format(
                      "could not create new property for '%s'; an error ('%s') occurred",
                      propertyIdentifier1, MAPPER.writeValueAsString(errorNode));

              throw new WikidataImporterException(message);
            }

            final JsonNode messagesJSON = errorNode.get(MEDIAWIKI_MESSAGES_IDENTIFIER);

            if (messagesJSON == null || messagesJSON.size() <= 0) {

              final String message =
                  String.format(
                      "could not create new property for '%s'; an error ('%s') occurred",
                      propertyIdentifier1, MAPPER.writeValueAsString(errorNode));

              throw new WikidataImporterException(message);
            }

            final JsonNode firstMessageNode = messagesJSON.get(0);

            if (firstMessageNode == null) {

              final String message =
                  String.format(
                      "could not create new property for '%s'; an error ('%s') occurred",
                      propertyIdentifier1, MAPPER.writeValueAsString(errorNode));

              throw new WikidataImporterException(message);
            }

            final JsonNode errorMessageNameNode = firstMessageNode.get(MEDIAWKI_NAME_IDENTIFIER);

            final String errorMessageName = errorMessageNameNode.asText();

            if (!WIKIBASE_VALIDATOR_LABEL_CONFLICT_ERROR_MESSAGE_NAME.equals(errorMessageName)) {

              final String message =
                  String.format(
                      "could not create new property for '%s'; an error ('%s') occurred",
                      propertyIdentifier1, MAPPER.writeValueAsString(errorNode));

              throw new WikidataImporterException(message);
            }

            final JsonNode errorMessageParametersNode =
                firstMessageNode.get(MEDIAWIKI_PARAMETERS_IDENTIFIER);

            if (errorMessageParametersNode == null || errorMessageParametersNode.size() < 3) {

              final String message =
                  String.format(
                      "could not create new property for '%s'; an error ('%s') occurred",
                      propertyIdentifier1, MAPPER.writeValueAsString(errorNode));

              throw new WikidataImporterException(message);
            }

            final JsonNode thirdErrorMessageParameterNode = errorMessageParametersNode.get(2);

            if (thirdErrorMessageParameterNode == null) {

              final String message =
                  String.format(
                      "could not create new property for '%s'; an error ('%s') occurred",
                      propertyIdentifier1, MAPPER.writeValueAsString(errorNode));

              throw new WikidataImporterException(message);
            }

            // extract the property id from this value
            final String thirdErrorMessageParameter = thirdErrorMessageParameterNode.asText();

            final Optional<String> optionalPropertyId = findPropertyId(thirdErrorMessageParameter);

            if (!optionalPropertyId.isPresent()) {

              final String message =
                  String.format(
                      "could not create new property for '%s'; an error ('%s') occurred",
                      propertyIdentifier1, MAPPER.writeValueAsString(errorNode));

              throw new WikidataImporterException(message);
            }

            final String propertyId = optionalPropertyId.get();

            return Datamodel.makePropertyIdValue(propertyId, null);
          } catch (final WikidataImporterException e1) {

            throw WikidataImporterError.wrap(e1);
          } catch (final Exception e) {

            final String message2 = "something went wrong, while trying to create a new property";

            throw WikidataImporterError.wrap(new WikidataImporterException(message2, e));
          }
        });
  }