001/*
002 * Copyright (c) 2003-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2012-11-26 22:21:34 +0000 (Mon, 26 Nov 2012) $' 
007 * '$Revision: 31119 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.kepler.kar;
031
032import java.io.IOException;
033import java.util.List;
034import java.util.StringTokenizer;
035import java.util.Vector;
036import java.util.jar.Attributes;
037import java.util.jar.Attributes.Name;
038import java.util.jar.JarEntry;
039import java.util.zip.ZipEntry;
040
041import org.apache.commons.logging.Log;
042import org.apache.commons.logging.LogFactory;
043import org.kepler.kar.karxml.KarXml;
044import org.kepler.objectmanager.lsid.KeplerLSID;
045
046/**
047 * Represents one entry that is contained inside of a KAR file.
048 */
049public class KAREntry extends JarEntry {
050        private static final Log log = LogFactory.getLog(KAREntry.class.getName());
051        private static final boolean isDebugging = log.isDebugEnabled();
052
053        Attributes _attributes = new Attributes();
054
055        /**
056         * <code>Name</code> object for <code>lsid</code> manifest attribute used
057         * for globally identifying KAREntries as unique.
058         */
059        public static final Name LSID = new Name("lsid");
060
061        /**
062         * <code>Name</code> object for <code>type</code> manifest attribute used
063         * for specifying the type of object contained by the KAREntry.
064         */
065        public static final Name TYPE = new Name("type");
066
067        /**
068         * <code>Name</code> object for <code>handler</code> manifest
069         * attribute used for identifying which KAREntry handler was used
070         * to write this KAREntry.
071         */
072        public static final Name HANDLER = new Name("handler");
073
074        /**
075         * <code>Name</code> object for <code>lsid_dependencies</code> manifest
076         * attribute used for identifying other KAREntries that this entry depends
077         * on.
078         */
079        public static final Name LSID_DEPENDENCIES = new Name("dependsOn");
080
081        /**
082         * create a karentry from a jarentry
083         */
084        public KAREntry(JarEntry je) {
085                super(je);
086                try {
087                        Attributes atts = je.getAttributes();
088                        if (atts == null) {
089                                _attributes = new Attributes();
090                        } else {
091                                _attributes = atts;
092                        }
093                } catch (IOException e) {
094                        e.printStackTrace();
095                }
096                if (isDebugging)
097                        log.debug(this.debugString());
098        }
099
100        /**
101         * create a karentry from a name
102         */
103        public KAREntry(String name) {
104                super(name);
105        }
106
107        /**
108         * create a karentry from a zipentry
109         */
110        public KAREntry(ZipEntry ze) {
111                super(ze);
112        }
113
114        /**
115         * @return
116         */
117        public boolean isValid() {
118                if (isDebugging) log.debug("isValid()");
119                if (getLSID() == null) {
120                        return false;
121                }
122                if (getType() == null) {
123                        return false;
124                }
125                if (getType().trim().equals("")) {
126                        return false;
127                }
128                if (getHandler() == null) {
129                        return false;
130                }
131                if (getHandler().trim().equals("")) {
132                        return false;
133                }
134                return true;
135        }
136
137        /**
138         * @return KeplerLSID or null
139         */
140        public KeplerLSID getLSID() {
141                try {
142                        String lsidStr = _attributes.getValue(LSID);
143                        if (lsidStr == null) {
144                                log.warn("no LSID for KAREntry " + getName());
145                                return null;
146                        }
147                        return new KeplerLSID(lsidStr);
148                } catch (Exception e) {
149                        log.warn("KAREntry lsid error: " + e.getMessage());
150                        return null;
151                }
152        }
153
154        /**
155         * @param lsid
156         * @throws IOException
157         */
158        public void setLSID(KeplerLSID lsid) throws IOException {
159                if (_attributes.containsKey(LSID)) {
160                        _attributes.remove(LSID);
161                }
162                _attributes.put(LSID, lsid.toString());
163        }
164
165        /**
166         * @return
167         */
168        public String getType() {
169                String type = _attributes.getValue(TYPE);
170                if (type == null) {
171                        log.warn("no type for KAREntry");
172                        return null;
173                }
174                return type;
175        }
176        
177        /**
178         * Determine if the kar entry is report layout
179         * @return true if the type is ReportLayout
180         */
181        public boolean isReportLayout(){
182          String type = _attributes.getValue(TYPE);
183          if(type != null && type.contains(KarXml.REPORTLAYOUT)){
184            return true;
185          }
186          else{
187            return false;
188          }
189        }
190
191        /**
192         * @param type
193         * @throws IOException
194         */
195        public void setType(String type) throws IOException {
196                if (_attributes.containsKey(TYPE)) {
197                        _attributes.remove(TYPE);
198                }
199                _attributes.put(TYPE, type);
200        }
201
202        /**
203         * @return
204         */
205        public String getHandler() {
206                String handler = _attributes.getValue(HANDLER);
207                if (handler == null) {
208                        log.warn("no handler for KAREntry: " + getName() + " " + getLSID());
209                        return null;
210                }
211                return handler;
212        }
213
214        /**
215         * @param handler
216         * @throws IOException
217         */
218        public void setHandler(String handler) throws IOException {
219                if (_attributes.containsKey(HANDLER)) {
220                        _attributes.remove(HANDLER);
221                }
222                _attributes.put(HANDLER, handler);
223        }
224
225        /**
226         * @return
227         */
228        public List<KeplerLSID> getLsidDependencies() {
229                Vector<KeplerLSID> depList = parseLsidDependencies(getAttributes());
230                return depList;
231
232        }
233
234
235        /**
236         * @param atts
237         * @return
238         */
239        public static Vector<KeplerLSID> parseLsidDependencies(Attributes atts) {
240
241                Vector<KeplerLSID> depList = new Vector<KeplerLSID>(2);
242                if (atts == null)
243                        return depList;
244
245                String ld = atts.getValue(KAREntry.LSID_DEPENDENCIES);
246                if (ld == null) {
247                        return depList;
248                }
249
250                StringTokenizer st = new StringTokenizer(ld, ":");
251                while (st.hasMoreTokens()) {
252                        try {
253                                String lsidStr = st.nextToken() + ":" + st.nextToken() + ":"
254                                                + st.nextToken() + ":" + st.nextToken() + ":"
255                                                + st.nextToken() + ":" + st.nextToken();
256                                KeplerLSID lsid = new KeplerLSID(lsidStr);
257                                depList.add(lsid);
258                        } catch (Exception e) {
259                                e.printStackTrace();
260                        }
261                }
262                return depList;
263        }
264
265        /**
266         * @param lsid
267         */
268        public void addLsidDependency(KeplerLSID lsid) {
269                if (isDebugging) log.debug("addLsidDependency("+lsid+")");
270                if (this.dependsOn(lsid)) {
271                        // it is already in the list
272                        // do nothing
273                } else {
274                        String ld = _attributes.getValue(LSID_DEPENDENCIES);
275                        if (ld == null || ld.trim().equals("")) {
276                                ld = "";
277                                ld += lsid.toString();
278                        } else {
279                                ld += ":" + lsid.toString();
280                        }
281                        _attributes.remove(LSID_DEPENDENCIES);
282                        _attributes.put(LSID_DEPENDENCIES, ld);
283                }
284                if (isDebugging) {
285                        log.debug(_attributes.getValue(LSID_DEPENDENCIES));
286                }
287        }
288
289        /**
290         * @param lsid
291         */
292        public void removeLsidDependency(KeplerLSID lsid) {
293                if (isDebugging) log.debug("removeLsidDependency("+lsid+")");
294                if (isDebugging) {
295                        log.debug(_attributes.getValue(LSID_DEPENDENCIES));
296                }
297                if (this.dependsOn(lsid)) {
298                        List<KeplerLSID> deps = getLsidDependencies();
299                        deps.remove(lsid);
300                        String newList = "";
301                        int i = 0;
302                        for (KeplerLSID dep : deps) {
303                                if (i == 0) {
304                                        newList += dep.toString();
305                                } else {
306                                        newList += ":" + dep.toString();
307                                }
308                                i++;
309                        }
310                        _attributes.remove(LSID_DEPENDENCIES);
311                        _attributes.put(LSID_DEPENDENCIES, newList);
312                } else {
313                        // do nothing
314                        // it is not in the list
315                }
316                if (isDebugging) {
317                        log.debug(_attributes.getValue(LSID_DEPENDENCIES));
318                }
319        }
320
321        /**
322         * @param lsid
323         * @return
324         */
325        public boolean dependsOn(KeplerLSID lsid) {
326                for (KeplerLSID l : getLsidDependencies()) {
327                        if (l.equals(lsid)) {
328                                return true;
329                        }
330                }
331                return false;
332        }
333
334
335        /**
336         * get the attributes object for this entry
337         */
338        public Attributes getAttributes() {
339                return _attributes;
340        }
341
342        /**
343         * @param name
344         * @param value
345         */
346        public void addAttribute(String name, String value) {
347                _attributes.put(new Attributes.Name(name), value);
348        }
349
350        /**
351         * @return
352         */
353        private String debugString() {
354                String s = "KAREntry: " + "\n  name=" + getName() + "\n  lsid="
355                                + getLSID() + "\n  type=" + getType() + "\n  handler="
356                                + getHandler() + "\n lsidDependencies="
357                                + getLsidDependencies();
358                return s;
359        }
360
361}