001/* 002 * SPDX-License-Identifier: Apache-2.0 003 * 004 * Copyright 2024-2026 The Enola <https://enola.dev> Authors 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package dev.enola.common; 019 020import static java.util.Objects.requireNonNull; 021 022import com.google.common.reflect.TypeToken; 023 024import java.util.Objects; 025 026public final class MutableObjectWithTypeToken<T> implements ObjectWithTypeToken<T> { 027 028 private final TypeToken<T> typeToken; 029 private T object; 030 031 public MutableObjectWithTypeToken(TypeToken<T> typeToken) { 032 this.typeToken = requireNonNull(typeToken); 033 } 034 035 @Override 036 public TypeToken<T> typeToken() { 037 return typeToken; 038 } 039 040 public void set(ObjectWithTypeToken<?> objectWithTypeToken) { 041 if (!objectWithTypeToken.typeToken().equals(typeToken)) { 042 throw new IllegalArgumentException( 043 "Cannot set a " + objectWithTypeToken + " into a " + typeToken); 044 } 045 set(objectWithTypeToken, this); 046 } 047 048 @SuppressWarnings("unchecked") 049 private void set(ObjectWithTypeToken<?> from, MutableObjectWithTypeToken<?> into) { 050 var fromWithObject = (ObjectWithTypeToken<Object>) from; 051 var intoWithObject = (MutableObjectWithTypeToken<Object>) into; 052 intoWithObject.setObject(fromWithObject.object()); 053 } 054 055 public void setObject(T object) { 056 if (!typeToken.getRawType().isInstance(object)) { 057 throw new IllegalArgumentException( 058 typeToken.toString() + " expected, but got: " + object.toString()); 059 } 060 this.object = requireNonNull(object); 061 } 062 063 @Override 064 public T object() { 065 return object; 066 } 067 068 @Override 069 public boolean equals(Object o) { 070 if (this == o) return true; 071 if (!(o instanceof MutableObjectWithTypeToken<?> that)) return false; 072 return Objects.equals(typeToken, that.typeToken) && Objects.equals(object, that.object); 073 } 074 075 @Override 076 public int hashCode() { 077 return Objects.hash(typeToken, object); 078 } 079 080 @Override 081 public String toString() { 082 return "MutableObjectWithTypeToken{" 083 + "typeToken=" 084 + typeToken 085 + ", object=" 086 + object 087 + '}'; 088 } 089}