/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.apache.isis.applib.services.bookmark;
import java.io.Serializable;
import java.util.Iterator;
import com.google.common.base.Splitter;
import org.apache.isis.applib.annotation.Value;
import org.apache.isis.schema.common.v1.BookmarkObjectState;
import org.apache.isis.schema.common.v1.OidDto;
/**
* String representation of any persistent object managed by the framework.
*
* <p>
* Analogous to the <tt>RootOid</tt>.
*/
@Value
public class Bookmark implements Serializable {
private static final long serialVersionUID = 1L;
protected static final char SEPARATOR = ':';
public OidDto toOidDto() {
final OidDto oidDto = new OidDto();
oidDto.setType(getObjectType());
oidDto.setId(getIdentifier());
// persistent is assumed if not specified...
final BookmarkObjectState bookmarkState = getObjectState().toBookmarkState();
oidDto.setObjectState(bookmarkState != BookmarkObjectState.PERSISTENT ? bookmarkState : null);
return oidDto;
}
public static Bookmark from(final OidDto oidDto) {
final BookmarkObjectState bookmarkObjectState = oidDto.getObjectState();
final ObjectState objectState = ObjectState.from(bookmarkObjectState);
final String objectType = coalesce(oidDto.getType(), oidDto.getObjectType());
final String objectId = coalesce(oidDto.getId(), oidDto.getObjectIdentifier());
final Bookmark bookmark = new Bookmark(objectState.getCode() + objectType, objectId);
return bookmark;
}
private static String coalesce(final String first, final String second) {
return first != null? first: second;
}
public enum ObjectState {
PERSISTENT("", BookmarkObjectState.PERSISTENT),
TRANSIENT("!", BookmarkObjectState.TRANSIENT), // same as OidMarshaller
VIEW_MODEL("*", BookmarkObjectState.VIEW_MODEL); // same as OidMarshaller
private final String code;
private final BookmarkObjectState bookmarkObjectState;
ObjectState(
final String code,
final BookmarkObjectState bookmarkObjectState) {
this.code = code;
this.bookmarkObjectState = bookmarkObjectState;
}
public boolean isTransient() {
return this == TRANSIENT;
}
public boolean isViewModel() {
return this == VIEW_MODEL;
}
public boolean isPersistent() {
return this == PERSISTENT;
}
public String getCode() {
return code;
}
public static ObjectState from(final String objectType) {
if(objectType.startsWith(TRANSIENT.code)) return TRANSIENT;
if(objectType.startsWith(VIEW_MODEL.code)) return VIEW_MODEL;
return PERSISTENT;
}
public static ObjectState from(final BookmarkObjectState objectState) {
if(objectState == null) {
return ObjectState.PERSISTENT;
}
switch (objectState) {
case TRANSIENT:
return ObjectState.TRANSIENT;
case VIEW_MODEL:
return ObjectState.VIEW_MODEL;
case PERSISTENT:
return ObjectState.PERSISTENT;
default:
// persistent is assumed if not specified
return ObjectState.PERSISTENT;
}
}
public BookmarkObjectState toBookmarkState() {
return bookmarkObjectState;
}
}
protected final String objectType;
private final String identifier;
protected final ObjectState state;
/**
* Round-trip with {@link #toString()} representation.
*/
public Bookmark(final String toString) {
this(Splitter.on(SEPARATOR).split(toString).iterator());
}
private Bookmark(final Iterator<String> split) {
this(split.next(), split.next());
}
public Bookmark(final String objectType, final String identifier) {
this.state = ObjectState.from(objectType);
this.objectType = state != ObjectState.PERSISTENT ? objectType.substring(1): objectType;
this.identifier = identifier;
}
public ObjectState getObjectState() {
return state;
}
public String getObjectType() {
return objectType;
}
public String getIdentifier() {
return identifier;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((identifier == null) ? 0 : identifier.hashCode());
result = prime * result + ((objectType == null) ? 0 : objectType.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Bookmark other = (Bookmark) obj;
if (identifier == null) {
if (other.identifier != null)
return false;
} else if (!identifier.equals(other.identifier))
return false;
if (objectType == null) {
if (other.objectType != null)
return false;
} else if (!objectType.equals(other.objectType))
return false;
return true;
}
/**
* The canonical form of the {@link Bookmark}, that is "{@link #getObjectType() objectType}{@value #SEPARATOR}{@link #getIdentifier()}".
*
* <p>
* This is parseable by the {@link #Bookmark(String) string constructor}.
*/
@Override
public String toString() {
return state.getCode() + objectType + SEPARATOR + identifier;
}
public static class AsStringType {
private AsStringType() {}
public static class Meta {
/**
* Is based on the defacto limit of a request URL in web browsers such as IE8
*/
public static final int MAX_LEN = 2000;
private Meta() {}
}
}
}