/**
* Licensed to Apereo under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright ownership. Apereo
* licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the License at the
* following location:
*
* <p>http://www.apache.org/licenses/LICENSE-2.0
*
* <p>Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apereo.portal.character.stream.events;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.springframework.util.Assert;
/**
*/
public final class CharacterDataEventImpl implements CharacterDataEvent {
private static final long serialVersionUID = 1L;
/** Character data for an empty string */
public static final CharacterDataEvent EMPTY_CHARACTER_DATA = new CharacterDataEventImpl("");
//Since the cache using weak refs for the events it should never be a cause for object retention therefor no max-size is needed
private static final LoadingCache<String, CharacterDataEvent> WEAK_EVENT_CACHE =
CacheBuilder.newBuilder()
.weakValues()
.recordStats()
.build(
new CacheLoader<String, CharacterDataEvent>() {
@Override
public CharacterDataEvent load(String data) throws Exception {
return new CharacterDataEventImpl(data);
}
});
public static CharacterDataEvent create(String data) {
if (data.length() == 0) {
return EMPTY_CHARACTER_DATA;
}
CharacterDataEvent event = WEAK_EVENT_CACHE.getIfPresent(data);
if (event == null) {
//Make sure the String reference is using a minimal char[]
data = new String(data);
event = WEAK_EVENT_CACHE.getUnchecked(data);
}
return event;
}
static Cache<String, CharacterDataEvent> getEventCache() {
return WEAK_EVENT_CACHE;
}
private final String data;
private int hash = 0;
private CharacterDataEventImpl(String data) {
Assert.notNull(data);
this.data = data;
}
/* (non-Javadoc)
* @see org.apereo.portal.character.stream.events.CharacterDataEvent#getData()
*/
@Override
public String getData() {
return this.data;
}
/* (non-Javadoc)
* @see org.apereo.portal.character.stream.events.CharacterEvent#getEventType()
*/
@Override
public CharacterEventTypes getEventType() {
return CharacterEventTypes.CHARACTER;
}
@Override
public String toString() {
return "CharacterDataEvent [data=" + this.data + "]";
}
@Override
public int hashCode() {
int h = hash;
if (h == 0) {
h = internalHashCode();
hash = h;
}
return h;
}
private int internalHashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getEventType().hashCode();
result = prime * result + ((data == null) ? 0 : data.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof CharacterDataEvent)) return false;
CharacterDataEvent other = (CharacterDataEvent) obj;
if (data == null) {
if (other.getData() != null) return false;
} else if (!data.equals(other.getData())) return false;
if (getEventType() == null) {
if (other.getEventType() != null) return false;
} else if (!getEventType().equals(other.getEventType())) return false;
return true;
}
}