Commit 0e347009 authored by Mihai Nita's avatar Mihai Nita

Prepare for 1.1.9

parents a80b3fa3 6abd2397
Pipeline #55378138 passed with stage
in 1 minute and 40 seconds
......@@ -6,14 +6,12 @@ There is an introduction to XLIFF 2.0 [in this Multilingual article](https://mul
* [ ![Download](https://api.bintray.com/packages/okapi/Distribution/Okapi_XLIFF_Toolkit/images/download.svg)](https://bintray.com/okapi/Distribution/Okapi_XLIFF_Toolkit/_latestVersion)
The latest stable version of the XLIFF Toolkit is at https://bintray.com/okapi/Distribution/Okapi_XLIFF_Toolkit
* The latest release Maven artifact is here: [http://repository-okapi.forge.cloudbees.com/release/](http://repository-okapi.forge.cloudbees.com/release/)
* The latest release Maven artifact is here: [https://search.maven.org/search?q=net.sf.okapi](https://search.maven.org/search?q=net.sf.okapi)
* Get the latest snapshot (development version) here: [okapi-xliffLib_all-platforms_<version>.zip](http://okapiframework.org/snapshots/)
* the latest snapshot Maven artifact is here: [http://repository-okapi.forge.cloudbees.com/snapshot/](http://repository-okapi.forge.cloudbees.com/snapshot/)
* On-line validation of XLIFF 2 documents: **http://okapi-lynx.appspot.com/validation**
* The latest snapshot Maven artifacts are here: [https://oss.sonatype.org/content/repositories/snapshots/](https://oss.sonatype.org/content/repositories/snapshots/)
* On-line validation of XLIFF 2 documents: http://okapi-lynx.appspot.com/validation
* You can now edit XLIFF 2 files in [OmegaT](http://www.omegat.org/en/omegat.html) using the [Okapi Filter Plugin](http://okapiframework.org/wiki/index.php?title=Okapi_Filters_Plugin_for_OmegaT#Support_for_XLIFF_2).
* Get a [set of valid and invalid XLIFF 2 documents](https://tools.oasis-open.org/version-control/browse/wsvn/xliff/trunk/xliff-20/test-suite/) to test if a XLIFF 2 user agent is reading documents properly.
* Read the **[Getting Started guide](https://bitbucket.org/okapiframework/xliff-toolkit/wiki)**.
* Read the [Getting Started guide](https://bitbucket.org/okapiframework/xliff-toolkit/wiki).
* Read the [Java Documentation](http://okapiframework.org/xlifflib/javadoc/) of the library.
* See also the tentative / prototyping object model for XLIFF and JSON serialization for XLIFF being worked on here: https://www.oasis-open.org/committees/xliff-omos.
![CloudBees: https://okapi.ci.cloudbees.com/](http://web-static-cloudfront.s3.amazonaws.com/images/badges/BuiltOnDEV.png)
\ No newline at end of file
......@@ -3,7 +3,7 @@
<parent>
<artifactId>xlifftk-build-applications</artifactId>
<groupId>net.sf.okapi.applications</groupId>
<version>1.1.8</version>
<version>1.1.9</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xlifftk-okapi-application-integration-tests</artifactId>
......
......@@ -8,7 +8,7 @@
<parent>
<groupId>net.sf.okapi.applications</groupId>
<artifactId>lynx-web</artifactId>
<version>1.1.8</version>
<version>1.1.9</version>
</parent>
<build>
......@@ -35,7 +35,7 @@
<dependency>
<groupId>net.sf.okapi.applications</groupId>
<artifactId>lynx-web-war</artifactId>
<version>1.1.8</version>
<version>1.1.9</version>
<type>war</type>
</dependency>
</dependencies>
......
......@@ -3,7 +3,7 @@
<display-name>appengine-modules-ear</display-name>
<module>
<web>
<web-uri>lynx-web-war-1.1.8.war</web-uri>
<web-uri>lynx-web-war-1.1.9.war</web-uri>
<context-root>/lynx-web-war</context-root>
</web>
</module>
......
......@@ -8,7 +8,7 @@
<parent>
<groupId>net.sf.okapi.applications</groupId>
<artifactId>lynx-web</artifactId>
<version>1.1.8</version>
<version>1.1.9</version>
</parent>
<properties>
......
......@@ -11,7 +11,7 @@
<ul>
<!-- <li>Host Address: <%=java.net.InetAddress.getLocalHost().getHostAddress()%></li> -->
<li>XLIFF Toolkit Project: <a target='_blank' href='https://bitbucket.org/okapiframework/xliff-toolkit'>https://bitbucket.org/okapiframework/xliff-toolkit</a></li>
<li>XLIFF Library version: 1.1.8 <!-- <%=net.sf.okapi.lib.xliff2.Const.class.getPackage().getImplementationVersion()%> --></li>
<li>XLIFF Library version: 1.1.9 <!-- <%=net.sf.okapi.lib.xliff2.Const.class.getPackage().getImplementationVersion()%> --></li>
</ul>
<h3>Services Available</h3>
<ul>
......
......@@ -5,7 +5,7 @@
<parent>
<artifactId>xlifftk-build-applications</artifactId>
<groupId>net.sf.okapi.applications</groupId>
<version>1.1.8</version>
<version>1.1.9</version>
</parent>
<artifactId>lynx-web</artifactId>
<packaging>pom</packaging>
......
......@@ -3,7 +3,7 @@
<parent>
<artifactId>xlifftk-build-applications</artifactId>
<groupId>net.sf.okapi.applications</groupId>
<version>1.1.8</version>
<version>1.1.9</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>okapi-application-lynx</artifactId>
......
......@@ -3,7 +3,7 @@
<parent>
<artifactId>xlifftk-build-okapi</artifactId>
<groupId>net.sf.okapi</groupId>
<version>1.1.8</version>
<version>1.1.9</version>
<relativePath>../okapi/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
......@@ -11,6 +11,11 @@
<groupId>net.sf.okapi.applications</groupId>
<packaging>pom</packaging>
<name>Okapi Applications Build</name>
<properties>
<maven.deploy.skip>false</maven.deploy.skip>
</properties>
<modules>
<module>lynx</module>
<!-- do not add integration-tests here as it needs to be run separately -->
......
<?xml version="1.0"?>
<settings>
<servers>
<server>
<id>sonatype</id>
<username>${MAVEN_REPO_USER}</username>
<password>${MAVEN_REPO_PASS}</password>
</server>
</servers>
<profiles>
<profile>
<id>sign_and_deploy</id>
<properties>
<gpg.executable>gpg</gpg.executable>
<gpg.passphrase>${GPG_PASSPHRASE}</gpg.passphrase>
</properties>
<repositories>
<repository>
<id>sonatype</id>
<name>Snapshots Repository for Downloads</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
</settings>
FROM openjdk:8u171-jdk-slim
RUN apt-get -q update --yes \
&& apt-get -q install --yes --no-install-recommends git maven ant curl gpg \
&& rm -rf /var/lib/apt/lists/*
RUN echo ============== && \
java -version && \
javac -version && \
mvn -version && \
ant -version && \
git --version && \
gpg --version && \
curl --version
WORKDIR /root
ENTRYPOINT /bin/bash
# Overview
By adding a `.gitlab-ci.yml` file to the root directory of the source
repository and configuring the GitLab project to use
[a Runner](https://docs.gitlab.com/ee/ci/runners/README.html) you are
activating [GitLab's continuous integration service](https://about.gitlab.com/product/continuous-integration),
which in its turn will give you an ability to automatically trigger
your CI [pipeline](https://docs.gitlab.com/ee/ci/pipelines.html) for
each push to the repository. For more general information please refer
to [the getting started guide](https://docs.gitlab.com/ee/ci/quick_start/README.html).
# Bitbucket integration
GitLab CI/CD can be used with GitHub or any other Git server. Instead
of moving the entire project to GitLab, we will connect our Butbucket
repository to get the benefits of GitLab CI/CD. That will set up
repository mirroring and create a lightweight project where issues,
merge requests, wiki, and snippets disabled (these features can be
re-enabled later).
Below are the steps required to be taken.
1. In GitLab create a **CI/CD for external repo**, select **Repo by URL**
and create the project. GitLab will import the repository and enable
Pull Mirroring.
2. In GitLab create a [Personal Access Token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html)
with api scope. This will be used to authenticate requests from the web
hook that will be created in Bitbucket to notify GitLab of new commits.
3. In Bitbucket from **Settings > Webhooks** create a new web hook to
notify GitLab of new commits.
The web hook URL should be set to the GitLab API to trigger pull
mirroring, using the Personal Access Token, which has been just
generated for the authentication. The web hook Trigger should be set
to ‘Repository Push’.
```
https://gitlab.com/api/v4/projects/<CI_PROJECT_ID>/mirror/pull?private_token=<PERSONAL_ACCESS_TOKEN>
```
`PERSONAL_ACCESS_TOKEN`: the generated personal access token
`CI_PROJECT_ID`: the GitLab project ID, it can be found on the
landing page of the project
4. In Bitbucket create an **App Password** from Bitbucket **Settings >
App Passwords** to authenticate the build status script setting commit
build statuses in Bitbucket. Repository write permissions are required.
5. In GitLab from **Settings > CI/CD > Variables** add variables to
allow communication with Bitbucket via the Bitbucket API.
`BITBUCKET_ACCESS_TOKEN`: the Bitbucket app password created above
`BITBUCKET_USERNAME`: the username of the Bitbucket account
`BITBUCKET_NAMESPACE`: set this if your GitLab and Bitbucket
namespaces differ
`BITBUCKET_REPOSITORY`: set this if your GitLab and Bitbucket
project names differ
The required `build-status` script can be found under `ci/gitlab` path.
GitLab should now be configured to mirror changes from Bitbucket,
run CI/CD pipelines configured in `.gitlab-ci.yml` and push the status
to Bitbucket.
For extra details please refer to [the original GitLab guide](https://docs.gitlab.com/ee/ci/ci_cd_for_external_repos/bitbucket_integration.html) .
# Triggering the Okapi project pipeline
When you get done with the Bitbucket integration, make sure the
following variables are declared:
`TRIGGER_TOKEN_OKAPI`: the trigger token which has to be added to the
Okapi project before that (needs to be added under
**Settings > CI/CD > Variables**)
`OKAPI_SNAPSHOTS_BRANCH`: the snapshots branch of Okapi project
`OKAPI_PROJECT_ID`: the Okapi project ID in GitLab, it can be found on
the landing page of the Okapi project
So, the following line from the `.gitlab-ci.yml` can be executed successfully:
```
curl -X POST -F token=${TRIGGER_TOKEN_OKAPI} -F ref=${OKAPI_SNAPSHOTS_BRANCH} https://gitlab.com/api/v4/projects/${OKAPI_PROJECT_ID}/trigger/pipeline
```
# Sonatype integration
The following secret variables have to be declared under
**Settings > CI/CD > Variables**:
`MAVEN_REPO_USER`: sonatype user
`MAVEN_REPO_PASS`: sonatype user's password
`OPENSSL_ENC_KEY`: the OpenSSL key for decoding the code signing key
`OPENSSL_ENC_IV`: the OpenSSL initialisation vector for decoding the code signing key
`GPG_PASSPHRASE`: the pass-phrase for the code signing key
#
# The jobs of one stage are going to be run simultaneously.
#
# The verification stage jobs:
# - verification
#
# The deployment stage jobs:
# - snapshot
# - release
#
# The trigger stage jobs:
# - okapi-snapshot-trigger
#
# Normally, on pushing to the code repository the "verification" job is run.
#
# If a branch is a "snapshot branch", then the "snapshot" job is run.
# If a branch is a "tag", then the "release" job is run.
#
# If a branch is a "snapshot branch", then the "okapi-snapshot-trigger"
# job is run.
#
# If any of the jobs fails, no other consequential job is run.
#
stages:
- verification
- deployment
- trigger
variables:
CI_GITLAB_PATH: "ci/gitlab"
CI_SCRIPTS_PATH: "${CI_GITLAB_PATH}/scripts"
DOCKER_DRIVER: "overlay2"
GIT_DEPTH: "3"
MAVEN_CLI_OPTS: "--settings ${CI_GITLAB_PATH}/.m2/settings.xml --batch-mode --errors --show-version"
OKAPI_PROJECT_ID: "okapiframework%2Fokapi"
OKAPI_SNAPSHOTS_BRANCH: "dev"
SNAPSHOTS_BRANCH: "dev"
# CI_DEBUG_TRACE: "true" # WARNING: all secret variables will be exposed to a job output!
image: registry.gitlab.com/okapiframework/okapi
before_script:
- ${CI_SCRIPTS_PATH}/before-job
after_script:
- ${CI_SCRIPTS_PATH}/after-job
verification:
stage: verification
cache:
paths:
- ${HOME}/.m2/repository/
before_script:
- ${CI_SCRIPTS_PATH}/before-job
script:
- mvn verify ${MAVEN_CLI_OPTS}
- touch ${CI_GITLAB_PATH}/${CI_JOB_NAME}-passed
.deployment: &deployment
stage: deployment
cache:
paths:
- ${HOME}/.m2/repository/
policy: pull
before_script:
- ${CI_SCRIPTS_PATH}/before-job
- ${CI_SCRIPTS_PATH}/gpg-import
script:
- mvn deploy ${MAVEN_CLI_OPTS} -DskipITs --activate-profiles sign_and_deploy,release #--quiet
- touch ${CI_GITLAB_PATH}/${CI_JOB_NAME}-passed
snapshot:
<<: *deployment
only:
variables:
- $SNAPSHOTS_BRANCH == $CI_COMMIT_REF_NAME
except:
- tags
- master
release:
<<: *deployment
only:
- tags
except:
- branches
okapi-snapshot-trigger:
stage: trigger
script:
- curl -X POST -F token=${TRIGGER_TOKEN_OKAPI} -F ref=${OKAPI_SNAPSHOTS_BRANCH} https://gitlab.com/api/v4/projects/${OKAPI_PROJECT_ID}/trigger/pipeline
- touch ${CI_GITLAB_PATH}/${CI_JOB_NAME}-passed
only:
variables:
- $SNAPSHOTS_BRANCH == $CI_COMMIT_REF_NAME
except:
- tags
- master
#!/usr/bin/env bash
if [ ! -f ${CI_GITLAB_PATH}/${CI_JOB_NAME}-passed ] ; then
BUILD_STATUS=failed ${CI_SCRIPTS_PATH}/build-status;
else
BUILD_STATUS=passed ${CI_SCRIPTS_PATH}/build-status;
fi
#!/usr/bin/env bash
rm -f ${CI_GITLAB_PATH}/${CI_JOB_NAME}-passed
BUILD_STATUS=running ${CI_SCRIPTS_PATH}/build-status
#!/usr/bin/env bash
# Push GitLab CI/CD build status to Bitbucket Cloud
if [ -z "$BITBUCKET_ACCESS_TOKEN" ]; then
echo "ERROR: BITBUCKET_ACCESS_TOKEN is not set"
exit 1
fi
if [ -z "$BITBUCKET_USERNAME" ]; then
echo "ERROR: BITBUCKET_USERNAME is not set"
exit 1
fi
if [ -z "$BITBUCKET_NAMESPACE" ]; then
echo "Setting BITBUCKET_NAMESPACE to $CI_PROJECT_NAMESPACE"
BITBUCKET_NAMESPACE=$CI_PROJECT_NAMESPACE
fi
if [ -z "$BITBUCKET_REPOSITORY" ]; then
echo "Setting BITBUCKET_REPOSITORY to $CI_PROJECT_NAME"
BITBUCKET_REPOSITORY=$CI_PROJECT_NAME
fi
BITBUCKET_API_ROOT="https://api.bitbucket.org/2.0"
BITBUCKET_STATUS_API="$BITBUCKET_API_ROOT/repositories/$BITBUCKET_NAMESPACE/$BITBUCKET_REPOSITORY/commit/$CI_COMMIT_SHA/statuses/build"
BITBUCKET_KEY="$CI_GITLAB_PATH/$CI_JOB_NAME"
BITBUCKET_NAME="$CI_JOB_STAGE:$CI_JOB_NAME:$BUILD_STATUS"
BITBUCKET_DESCRIPTION="Pipeline #$CI_PIPELINE_ID"
case "$BUILD_STATUS" in
running)
BITBUCKET_STATE="INPROGRESS"
;;
passed)
BITBUCKET_STATE="SUCCESSFUL"
;;
failed)
BITBUCKET_STATE="FAILED"
;;
esac
echo "Pushing status to $BITBUCKET_STATUS_API..."
curl --request POST $BITBUCKET_STATUS_API \
--user $BITBUCKET_USERNAME:$BITBUCKET_ACCESS_TOKEN \
--header "Content-Type:application/json" \
--write-out "[%{http_code}]" \
--silent \
--show-error \
--output /dev/null \
--data "{ \"state\": \"$BITBUCKET_STATE\",
\"key\": \"$BITBUCKET_KEY\",
\"name\": \"$BITBUCKET_NAME\",
\"description\": \"$BITBUCKET_DESCRIPTION\",
\"url\": \"$CI_JOB_URL\" }"
#!/usr/bin/env bash
GPG_CONF=".gnupg/gpg.conf"
GPG_AGENT_CONF=".gnupg/gpg-agent.conf"
OPENSSL_CLI_OPTS="enc -aes-256-cbc -K ${OPENSSL_ENC_KEY} -iv ${OPENSSL_ENC_IV}"
openssl ${OPENSSL_CLI_OPTS} -d -in ${CI_GITLAB_PATH}/code-signing-key.asc.enc -out ${CI_GITLAB_PATH}/code-signing-key.asc
gpg --quiet --batch --import ${CI_GITLAB_PATH}/code-signing-key.asc
echo "use-agent" > ${HOME}/${GPG_CONF}
echo "pinentry-mode loopback" >> ${HOME}/${GPG_CONF}
echo "allow-loopback-pinentry" > ${HOME}/${GPG_AGENT_CONF}
......@@ -4,16 +4,8 @@
<groupId>org.example</groupId>
<artifactId>xliff2lib-example</artifactId>
<packaging>jar</packaging>
<version>1.1.8</version>
<version>1.1.9</version>
<name>xliff2lib-example</name>
<repositories>
<repository> <!-- Repository for the XLIFF library -->
<id>okapi-xliff</id>
<name>okapi-xliff-repository</name>
<url>http://repository-okapi-xliff.forge.cloudbees.com/snapshot/</url>
<layout>default</layout>
</repository>
</repositories>
<build>
<pluginManagement>
<plugins>
......@@ -49,7 +41,7 @@
<dependency> <!-- XLIFF library -->
<groupId>net.sf.okapi.lib</groupId>
<artifactId>okapi-lib-xliff2</artifactId>
<version>1.1.8</version>
<version>1.1.9</version>
</dependency>
</dependencies>
</project>
......@@ -7,6 +7,11 @@
<body>
<h1>Changes Log - Okapi XLIFF Toolkit @version@, @date@</h1>
<h3>Changes in version @version@</h3>
<ul>
<li>None.</li>
</ul>
<h3>Changes in version 1.1.8</h3>
<ul>
<li>The toolkit is now compiled to Java 8.</li>
</ul>
......
......@@ -31,7 +31,7 @@
<li>This library has no dependency. This is the only file you need if
you are using the library with your own application.</li>
<li>You can also get this JAR from the project's Maven repository at <a
target="_blank" href="http://repository-okapi.forge.cloudbees.com/release/">http://repository-okapi.forge.cloudbees.com/release/</a>.
target="_blank" href="https://mvnrepository.com/artifact/net.sf.okapi.lib/okapi-lib-xliff2/">https://mvnrepository.com/artifact/net.sf.okapi.lib/okapi-lib-xliff2/</a>.
<br>
&nbsp;</li>
</ul>
......
# Version number should be incremented as needed
xlifflibVersion=1.1.8
xlifflibVersion=1.1.9
......@@ -4,7 +4,7 @@
<parent>
<artifactId>xlifftk-build-libraries</artifactId>
<groupId>net.sf.okapi.lib</groupId>
<version>1.1.8</version>
<version>1.1.9</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>okapi-lib-xliff2</artifactId>
......
......@@ -16,6 +16,8 @@
package net.sf.okapi.lib.xliff2.changeTracking;
import java.util.Objects;
import net.sf.okapi.lib.xliff2.Const;
import net.sf.okapi.lib.xliff2.Util;
import net.sf.okapi.lib.xliff2.core.DataWithExtAttributes;
......@@ -153,4 +155,38 @@ public class Item extends DataWithExtAttributes implements IWithExtAttributes {
return "</" + Const.PREFIXCOL_TRACKINGSd + TAG_NAME + ">";
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), property, text);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Item other = (Item) obj;
if (property == null) {
if (other.property != null) {
return false;
}
} else if (!property.equals(other.property)) {
return false;
}
if (text == null) {
if (other.text != null) {
return false;
}
} else if (!text.equals(other.text)) {
return false;
}
return true;
}
}
......@@ -16,6 +16,8 @@
package net.sf.okapi.lib.xliff2.core;
import java.util.Objects;
import net.sf.okapi.lib.xliff2.InvalidParameterException;
import net.sf.okapi.lib.xliff2.Util;
......@@ -102,27 +104,27 @@ public class CTag extends Tag {
}
@Override
public boolean equals (Tag tag) {
if ( tag == null ) return false;
if ( this == tag ) return true;
if ( !(tag instanceof CTag) ) return false;
CTag ctag = (CTag)tag;
if ( tagType.compareTo(ctag.getTagType()) != 0 ) return false;
if ( Util.compareAllowingNull(getId(), ctag.getId()) != 0 ) return false;
if ( !cc.equals(ctag.cc) ) return false;
if ( Util.compareAllowingNull(data, ctag.getData()) != 0 ) return false;
if ( Util.compareAllowingNull(dataRef, ctag.getDataRef()) != 0 ) return false;
if ( Util.compareAllowingNull(subFlows, ctag.getSubFlows()) != 0 ) return false;
if ( Util.compareAllowingNull(disp, ctag.getDisp()) != 0 ) return false;
if ( Util.compareAllowingNull(equiv, ctag.getEquiv()) != 0 ) return false;
if ( !getCanReorder().equals(ctag.getCanReorder()) ) return false;
if ( initialWithData != ctag.initialWithData ) return false;
if ( dataDir != ctag.dataDir ) return false;
public boolean equals(Object other) {
if (other == null) return false;
if (this == other) return true;
if (!(other instanceof CTag)) return false;
if (!super.equals(other)) return false;
CTag cTag = (CTag) other;
return initialWithData == cTag.initialWithData &&
Objects.equals(cc, cTag.cc) &&
Objects.equals(data, cTag.data) &&
Objects.equals(dataRef, cTag.dataRef) &&
dataDir == cTag.dataDir &&
Objects.equals(disp, cTag.disp) &&
Objects.equals(equiv, cTag.equiv) &&
Objects.equals(subFlows, cTag.subFlows) &&
canReorder == cTag.canReorder;
}
return true;
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), cc, data, initialWithData, dataRef, dataDir, disp, equiv, subFlows, canReorder);
}
@Override
......
......@@ -16,6 +16,8 @@
package net.sf.okapi.lib.xliff2.core;
import java.util.Objects;
import net.sf.okapi.lib.xliff2.Const;
import net.sf.okapi.lib.xliff2.InvalidParameterException;
import net.sf.okapi.lib.xliff2.Util;
......@@ -134,18 +136,29 @@ class CTagCommon {
this.dir = dir;
}
public boolean equals (CTagCommon other) {
if ( other == null ) return false;
if ( this == other) return true;
if ( Util.compareAllowingNull(getId(), other.getId()) != 0 ) return false;
if ( Util.compareAllowingNull(getType(), other.getType()) != 0 ) return false;
if ( Util.compareAllowingNull(getSubType(), other.getSubType()) != 0 ) return false;
if ( Util.compareAllowingNull(getCopyOf(), other.getCopyOf()) != 0 ) return false;
if ( getDir() != other.getDir() ) return false;
if ( getCanCopy() != other.getCanCopy() ) return false;
if ( getCanDelete() != other.getCanDelete() ) return false;
if ( getCanOverlap() != other.getCanOverlap() ) return false;
return true;
/**
* Indicates if this object is equals to a given one.
* @param other the other object to compare.
* @return true if the two objects are identical.
*/
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (this == other) return true;
if (!(other instanceof CTagCommon)) return false;
CTagCommon that = (CTagCommon) other;
return hints == that.hints &&
canOverlap == that.canOverlap &&
Objects.equals(id, that.id) &&
Objects.equals(type, that.type) &&
Objects.equals(subType, that.subType) &&
Objects.equals(copyOf, that.copyOf) &&
dir == that.dir;
}
@Override
public int hashCode() {
return Objects.hash(id, type, hints, canOverlap, subType, copyOf, dir);
}
}
......@@ -16,6 +16,9 @@
package net.sf.okapi.lib.xliff2.core;
import java.util.Iterator;
import java.util.Objects;
/**
* Implements the {@link IWithExtAttributes} interface.
*/
......@@ -66,5 +69,36 @@ public class DataWithExtAttributes implements IWithExtAttributes {
if ( xattrs == null ) return null;
return xattrs.getAttributeValue(namespaceURI, localName);
}
/**
* Indicates if this object is equals to a given one.
* @param other the other object to compare.
* @return true if the two objects are identical.
*/
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (this == other) return true;
if (!(other instanceof DataWithExtAttributes)) return false;
DataWithExtAttributes that = (DataWithExtAttributes) other;
if (this.xattrs == that.xattrs) return true;
if (this.xattrs