Person.java
001 /*
002  * Java GPX Library (jpx-3.1.0).
003  * Copyright (c) 2016-2023 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019  */
020 package io.jenetics.jpx;
021 
022 import static java.util.Objects.hash;
023 
024 import java.io.DataInput;
025 import java.io.DataOutput;
026 import java.io.IOException;
027 import java.io.InvalidObjectException;
028 import java.io.ObjectInputStream;
029 import java.io.Serial;
030 import java.io.Serializable;
031 import java.util.Objects;
032 import java.util.Optional;
033 
034 /**
035  * A person or organization.
036  *
037  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
038  @version 1.2
039  @since 1.0
040  */
041 public final class Person implements Serializable {
042 
043     @Serial
044     private static final long serialVersionUID = 2L;
045 
046     private final String _name;
047     private final Email _email;
048     private final Link _link;
049 
050     /**
051      * Create a new {@code Person} object with the given parameters.
052      *
053      @param name name of person or organization
054      @param email the person's email address
055      @param link link to Web site or other external information about person
056      */
057     private Person(final String name, final Email email, final Link link) {
058         _name = name;
059         _email = email;
060         _link = link;
061     }
062 
063     /**
064      * Return the name of the person or organization.
065      *
066      @return the name of the person or organization
067      */
068     public Optional<String> getName() {
069         return Optional.ofNullable(_name);
070     }
071 
072     /**
073      * Return the email address.
074      *
075      @return the email address
076      */
077     public Optional<Email> getEmail() {
078         return Optional.ofNullable(_email);
079     }
080 
081     /**
082      * Return the link to Web site or other external information about person.
083      *
084      @return the link to Web site or other external information about person
085      */
086     public Optional<Link> getLink() {
087         return Optional.ofNullable(_link);
088     }
089 
090     /**
091      * Return {@code true} if all person properties are {@code null}.
092      *
093      @return {@code true} if all person properties are {@code null}
094      */
095     public boolean isEmpty() {
096         return _name == null &&
097             _email == null &&
098             _link == null;
099     }
100 
101     /**
102      * Return {@code true} if not all person properties are {@code null}.
103      *
104      @since 1.1
105      *
106      @return {@code true} if not all person properties are {@code null}
107      */
108     public boolean nonEmpty() {
109         return !isEmpty();
110     }
111 
112     @Override
113     public int hashCode() {
114         return hash(_name, _email, _link);
115     }
116 
117     @Override
118     public boolean equals(final Object obj) {
119         return obj == this ||
120             obj instanceof Person person &&
121             Objects.equals(person._name, _name&&
122             Objects.equals(person._email, _email&&
123             Objects.equals(person._link, _link);
124     }
125 
126     @Override
127     public String toString() {
128         return Objects.toString(_name);
129     }
130 
131     /* *************************************************************************
132      *  Static object creation methods
133      * ************************************************************************/
134 
135     /**
136      * Create a new {@code Person} object with the given parameters.
137      *
138      @param name name of person or organization
139      @param email the person's email address
140      @param link link to Web site or other external information about person
141      @return a new {@code Person} object with the given parameters
142      */
143     public static Person of(final String name, final Email email, final Link link) {
144         return new Person(name, email, link);
145     }
146 
147     /**
148      * Create a new {@code Person} object with the given parameters.
149      *
150      @param name name of person or organization
151      @param email the person's email address
152      @return a new {@code Person} object with the given parameters
153      */
154     public static Person of(final String name, final Email email) {
155         return new Person(name, email, null);
156     }
157 
158     /**
159      * Create a new {@code Person} object with the given parameters.
160      *
161      @param name name of person or organization
162      @return a new {@code Person} object with the given parameters
163      */
164     public static Person of(final String name) {
165         return new Person(name, null, null);
166     }
167 
168     /**
169      * Create a new <i>empty</i> {@code Person}.
170      *
171      @return a new <i>empty</i> {@code Person}
172      */
173     public static Person of() {
174         return new Person(null, null, null);
175     }
176 
177 
178     /* *************************************************************************
179      *  Java object serialization
180      * ************************************************************************/
181 
182     @Serial
183     private Object writeReplace() {
184         return new SerialProxy(SerialProxy.PERSON, this);
185     }
186 
187     @Serial
188     private void readObject(final ObjectInputStream stream)
189         throws InvalidObjectException
190     {
191         throw new InvalidObjectException("Serialization proxy required.");
192     }
193 
194     void write(final DataOutput outthrows IOException {
195         IO.writeNullableString(_name, out);
196         IO.writeNullable(_email, Email::write, out);
197         IO.writeNullable(_link, Link::write, out);
198     }
199 
200     static Person read(final DataInput inthrows IOException {
201         return new Person(
202             IO.readNullableString(in),
203             IO.readNullable(Email::read, in),
204             IO.readNullable(Link::read, in)
205         );
206     }
207 
208 
209     /* *************************************************************************
210      *  XML stream object serialization
211      * ************************************************************************/
212 
213     static XMLWriter<Person> writer(final String name) {
214         return XMLWriter.elem(name,
215             XMLWriter.elem("name").map(person -> person._name),
216             Email.WRITER.map(person -> person._email),
217             Link.WRITER.map(person -> person._link)
218         );
219     }
220 
221     static XMLReader<Person> reader(final String name) {
222         return XMLReader.elem(
223             v -> Person.of((String)v[0](Email)v[1](Link)v[2]),
224             name,
225             XMLReader.elem("name"),
226             Email.READER,
227             Link.READER
228         );
229     }
230 
231 }