1
/*
2
 * Copyright (C) 2011 Openismus GmbH
3
 *
4
 * This file is part of GWT-Glom.
5
 *
6
 * GWT-Glom is free software: you can redistribute it and/or modify it
7
 * under the terms of the GNU Lesser General Public License as published by the
8
 * Free Software Foundation, either version 3 of the License, or (at your
9
 * option) any later version.
10
 *
11
 * GWT-Glom is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
14
 * for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with GWT-Glom.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
package org.glom.web.client.place;
21
22
import java.util.HashMap;
23
24
import org.glom.web.client.StringUtils;
25
import org.glom.web.shared.TypedDataItem;
26
import org.glom.web.shared.layout.LayoutItemField.GlomFieldType;
27
28
import com.google.gwt.place.shared.PlaceTokenizer;
29
import com.google.gwt.place.shared.Prefix;
30
31
public class DetailsPlace extends HasSelectableTablePlace {
32
	private final TypedDataItem primaryKeyValue;
33
34
	public DetailsPlace(final String documentID, final String tableName,
35
			final TypedDataItem primarykeyValue) {
36
		super(documentID, tableName);
37
		this.primaryKeyValue = primarykeyValue;
38
	}
39
40
	public TypedDataItem getPrimaryKeyValue() {
41
		return primaryKeyValue;
42
	}
43
44
	@Prefix("details")
45
	public static class Tokenizer extends HasSelectableTablePlace.Tokenizer implements PlaceTokenizer<DetailsPlace> {
46
47
		private final String primaryKeyValueKey = "value";
48
49
		/**
50
		 * Creates the URL string that is shown in the browser. This is the bookmarked URL.
51
		 * 
52
		 * @see com.google.gwt.place.shared.PlaceTokenizer#getToken(com.google.gwt.place.shared.Place)
53
		 * @see org.glom.web.server.Utils.getGlomTypeGdaValueForTypedDataItem(String, String, glom_field_type,
54
		 *      TypedDataItem)
55
		 */
56
		@Override
57
		public String getToken(final DetailsPlace place) {
58
			final TypedDataItem primaryKeyValue = place.getPrimaryKeyValue();
59
			final GlomFieldType glomFieldType = primaryKeyValue.getType();
60
61
			// create the URL string based on the
62
			String primaryKeyValueString = "";
63
			switch (glomFieldType) {
64
			case TYPE_NUMERIC:
65
				// non-locale specific number-to-string conversion:
66
				// http://docs.oracle.com/javase/6/docs/api/java/lang/Double.html#toString%28double%29
67
				primaryKeyValueString = Double.toString(primaryKeyValue.getNumber());
68
				// Remove the trailing point and zero on integers. This just makes URL string look nicer.
69
				if (primaryKeyValueString.endsWith(".0"))
70
					primaryKeyValueString = primaryKeyValueString.substring(0, primaryKeyValueString.length() - 2);
71
				break;
72
73
			case TYPE_TEXT:
74
				primaryKeyValueString = primaryKeyValue.getText();
75
				break;
76
77
			case TYPE_INVALID:
78
				final String urlText = primaryKeyValue.getUnknown();
79
				if (!primaryKeyValue.isEmpty() && urlText != null) {
80
					// An invalid type that's not empty indicates that primary key value has been created from a URL
81
					// string. Use the same string to represent the primary key value on the URL.
82
					primaryKeyValueString = urlText;
83
					// TODO: Update the primary key value string with the actual Gda Value that was created. The primary
84
					// key value could be different if the string-to-number conversion doesn't work.
85
				}
86
				break;
87
88
			default:
89
				// Unknown types are represented in the URL by an empty string. When loading a page with an unknown from
90
				// a URL (bookmark or link), the details view will run the query with an empty Value item based on the
91
				// type from the Glom document. The first result from this query will be shown. This means that the
92
				// specific record for unknown types are not bookmarkmarkable.
93
94
				// Support for bookmarking a new type can be added by adding a case statement for the new type here
95
				// and in this method:
96
				// org.glom.web.server.Utils.getGlomTypeGdaValueForTypedDataItem()
97
98
				// primaryKeyValueString remains empty
99
				break;
100
			}
101
102
			final HashMap<String, String> params = new HashMap<String, String>();
103
			params.put(documentKey, place.getDocumentID());
104
			params.put(tableKey, place.getTableName());
105
			params.put(primaryKeyValueKey, primaryKeyValueString);
106
			return buildParamsToken(params);
107
		}
108
109
		/**
110
		 * Create a DetailPlace that should be loaded from a URL string. This is called when users load the details view
111
		 * directly with the URL string (a bookmark or link).
112
		 * 
113
		 * @see com.google.gwt.place.shared.PlaceTokenizer#getPlace(java.lang.String)
114
		 * @see org.glom.web.server.Utils.getGlomTypeGdaValueForTypedDataItem(String, String, glom_field_type,
115
		 *      TypedDataItem)
116
		 */
117
		@Override
118
		public DetailsPlace getPlace(final String token) {
119
			// default empty values
120
			String documentID = "";
121
			String tableName = ""; // an empty value represents the default table
122
123
			final TypedDataItem primaryKeyValue = new TypedDataItem();
124
125
			final HashMap<String, String> params = getTokenParams(token);
126
127
			if (params == null) {
128
				return new DetailsPlace("", "", primaryKeyValue);
129
			}
130
131
			if (params.get(documentKey) != null) {
132
				documentID = params.get(documentKey);
133
			}
134
135
			if (params.get(tableKey) != null) {
136
				tableName = params.get(tableKey);
137
			}
138
139
			if (params.get(primaryKeyValueKey) != null) {
140
				final String primaryKeyValueString = params.get(primaryKeyValueKey);
141
				// Set as unknown because the type of the primary key is not known at this point. A proper primary key
142
				// value will be created using the type from the Glom document in the servlet.
143
				primaryKeyValue.setUnknown(primaryKeyValueString);
144
			}
145
146
			if (StringUtils.isEmpty(documentID)) {
147
				// The documentID was not retrieved from the URL. Use empty values for the details place.
148
				return new DetailsPlace("", "", primaryKeyValue);
149
			}
150
151
			return new DetailsPlace(documentID, tableName, primaryKeyValue);
152
		}
153
	}
154
155
}