Source code: jbreport/core/RepositoryImpl.java
1 /*
2 * $Id: RepositoryImpl.java,v 1.1 2000/08/31 13:53:17 grantfin Exp $
3 *
4 * jbReport - A reporting library for Java
5 * Copyright (C) 2000 Grant Finnemore <grantfin@users.sourceforge.net>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 package jbreport.core;
22
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.Map;
27 import org.xml.sax.Attributes;
28
29 import jbreport.ReportElement;
30 import jbreport.ReportException;
31 import jbreport.ReportSection;
32 import jbreport.ReportStylesheet;
33 import jbreport.Repository;
34 import jbreport.data.Datasource;
35 import jbreport.data.Query;
36
37 /**
38 * This represents a storage area for a bunch of other element types, including
39 * but not limited to, datasources, queries, documents, etc.
40 *
41 * <p> As many repositories are allowed, this class provides methods to search
42 * for repositories. It should be noted that a repository forms its' own
43 * namespace, and that elements such as queries can be obtained by referring
44 * to a given namespace. ie. should a Query x be required from Repository y,
45 * we can either get Repository y, and then call <code>getQuery("x")</code> on
46 * it, or if we already have a Repository z, then the call
47 * <code>getQuery("y.x")</code> will return the same Query element.
48 *
49 * @author Grant Finnemore
50 * @version $Revision: 1.1 $
51 */
52 public
53 class RepositoryImpl extends ReportCompositeImpl implements Repository {
54
55 /** Used as a key into the namedTypes map for the named queries */
56 private static final String QUERIES = "query";
57
58 /** Used as a key into the namedTypes map for the named datasources */
59 private static final String DATASOURCES = "datasource";
60
61 /** Used as a key into the namedTypes map for the named documents */
62 private static final String DOCUMENTS = "document";
63
64 /** Used as a key into the namedTypes map for the named fragments */
65 private static final String FRAGMENTS = "fragment";
66
67 /** Used as a key into the namedTypes map for the named stylesheets */
68 private static final String STYLESHEETS = "stylesheet";
69
70 /** The repositories that have been defined */
71 private static Map repositories = new HashMap();
72
73 /** This provides a map which contains other maps. This map is keyed by
74 * contained map type, while the contained maps are keyed by name. ie.
75 * (map type, (name, [query|datasource|document])).
76 */
77 private Map namedTypes = new HashMap();
78
79 //
80 // Constructors
81 //
82
83 //
84 // Static naming methods
85 //
86
87 public static Repository fetchRepository(String name)
88 throws ReportException {
89
90 if(name.indexOf('.') >= 0) {
91 name = name.substring(0, name.indexOf('.'));
92 }
93 Repository result = (Repository)repositories.get(name);
94 if(result == null) {
95 throw new ElementNotFoundException(name, Repository.class);
96 }
97 return result;
98 }
99
100 public static boolean exists(String name) {
101 return repositories.containsKey(name);
102 }
103
104 //
105 // Lookup methods for other named types that exist within this namespace
106 //
107
108 public Query fetchQuery(String name) throws ReportException {
109 return (Query)fetchNamedElement(name, QUERIES, Query.class);
110 }
111
112 public Datasource fetchDatasource(String name) throws ReportException {
113 return (Datasource)fetchNamedElement(name, DATASOURCES,
114 Datasource.class);
115 }
116
117 public ReportSection fetchDocument(String name) throws ReportException {
118 ReportElement elem =
119 fetchNamedElement(name, DOCUMENTS, ReportSection.class);
120 return (ReportSection)elem.copy(DEEP);
121 }
122
123 public Iterator documentNames() {
124 Map docs = (Map)namedTypes.get(DOCUMENTS);
125 return Collections.unmodifiableSet(docs.keySet()).iterator();
126 }
127
128 public ReportElement fetchFragment(String name) throws ReportException {
129 return fetchNamedElement(name, FRAGMENTS, ReportElement.class);
130 }
131
132 public ReportStylesheet fetchStylesheet(String name)
133 throws ReportException {
134 ReportElement elem =
135 fetchNamedElement(name, STYLESHEETS, ReportElement.class);
136 return (ReportStylesheet)elem;
137 }
138
139 //
140 // Methods overloaded from ReportCompositeImpl
141 //
142
143 public void xmlInitialize(String localName, Attributes attributes)
144 throws ReportException {
145
146 // This needs to be done before the children are parsed, as they insert
147 // elements against a named Repository instance.
148 super.xmlInitialize(localName, attributes);
149 if(getName() == null) {
150 throw new ReportException("The repository has not been given a name."
151 + " Was a name defined in the XML file?");
152 }
153 repositories.put(getName(), this);
154 }
155
156 public void xmlEndChild(ReportElement elem) throws ReportException {
157 super.xmlEndChild(elem);
158 if(elem.getName() != null && elem.getType() != null) {
159 insertNamedElement(elem, elem.getType());
160 }
161 }
162
163 //
164 // Methods overloaded from AbstractReportElement
165 //
166
167 public void accept(ReportVisitor visitor, ReportVisitorState state)
168 throws ReportException {
169 visitor.visitRepository(this, state);
170 }
171
172 //
173 // Implementation methods
174 //
175
176 private ReportElement fetchNamedElement(String name, String map, Class cls)
177 throws ReportException {
178
179 assertNotNull(name, "name");
180 int split = name.indexOf('.');
181 // Extract the name of the repository and element
182 String repositoryName = getName();
183 String elemName = name;
184 if(split >= 0) {
185 repositoryName = name.substring(0, split);
186 elemName = name.substring(split+1);
187 }
188 // Fetch the repository and appropriate named element map
189 RepositoryImpl repository =
190 (RepositoryImpl)fetchRepository(repositoryName);
191 Map namedElementMap = (Map)repository.namedTypes.get(map);
192 if(namedElementMap == null) {
193 throw new ElementNotFoundException(name, cls);
194 }
195 ReportElement elem = (ReportElement)namedElementMap.get(elemName);
196 if(elem == null) {
197 throw new ElementNotFoundException(name, cls);
198 }
199 return elem;
200 }
201
202 private void insertNamedElement(ReportElement elem, String map) {
203 String name = elem.getName();
204 if(name != null) {
205 Map namedElementMap = (Map)namedTypes.get(map);
206 if(namedElementMap == null) {
207 namedElementMap = new HashMap();
208 namedTypes.put(map, namedElementMap);
209 }
210 namedElementMap.put(name, elem);
211 }
212 }
213 }
214
215
216
217