001: /*
002: * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/naming/resources/ResourceAttributes.java,v 1.5 2002/03/09 23:21:49 remm Exp $
003: * $Revision: 1.5 $
004: * $Date: 2002/03/09 23:21:49 $
005: *
006: * ====================================================================
007: *
008: * The Apache Software License, Version 1.1
009: *
010: * Copyright (c) 1999 The Apache Software Foundation. All rights
011: * reserved.
012: *
013: * Redistribution and use in source and binary forms, with or without
014: * modification, are permitted provided that the following conditions
015: * are met:
016: *
017: * 1. Redistributions of source code must retain the above copyright
018: * notice, this list of conditions and the following disclaimer.
019: *
020: * 2. Redistributions in binary form must reproduce the above copyright
021: * notice, this list of conditions and the following disclaimer in
022: * the documentation and/or other materials provided with the
023: * distribution.
024: *
025: * 3. The end-user documentation included with the redistribution, if
026: * any, must include the following acknowlegement:
027: * "This product includes software developed by the
028: * Apache Software Foundation (http://www.apache.org/)."
029: * Alternately, this acknowlegement may appear in the software itself,
030: * if and wherever such third-party acknowlegements normally appear.
031: *
032: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
033: * Foundation" must not be used to endorse or promote products derived
034: * from this software without prior written permission. For written
035: * permission, please contact apache@apache.org.
036: *
037: * 5. Products derived from this software may not be called "Apache"
038: * nor may "Apache" appear in their names without prior written
039: * permission of the Apache Group.
040: *
041: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
042: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
043: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
044: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
045: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
046: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
047: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
048: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
049: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
050: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
051: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
052: * SUCH DAMAGE.
053: * ====================================================================
054: *
055: * This software consists of voluntary contributions made by many
056: * individuals on behalf of the Apache Software Foundation. For more
057: * information on the Apache Software Foundation, please see
058: * <http://www.apache.org/>.
059: *
060: * [Additional notices, if required by prior licensing conditions]
061: *
062: */
063:
064: package org.apache.naming.resources;
065:
066: import java.util.Hashtable;
067: import java.util.Vector;
068: import java.util.Enumeration;
069: import java.util.Date;
070: import java.util.StringTokenizer;
071: import java.util.Locale;
072: import java.text.SimpleDateFormat;
073: import java.text.DateFormat;
074: import java.text.ParseException;
075: import javax.naming.NamingException;
076: import javax.naming.NamingEnumeration;
077: import javax.naming.directory.Attributes;
078: import javax.naming.directory.BasicAttributes;
079: import javax.naming.directory.BasicAttribute;
080: import javax.naming.directory.Attribute;
081:
082: /**
083: * Attributes implementation.
084: *
085: * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
086: * @version $Revision: 1.5 $
087: */
088: public class ResourceAttributes implements Attributes {
089:
090: // -------------------------------------------------------------- Constants
091:
092: // Default attribute names
093:
094: /**
095: * Creation date.
096: */
097: public static final String CREATION_DATE = "creationdate";
098:
099: /**
100: * Creation date.
101: */
102: public static final String ALTERNATE_CREATION_DATE = "creation-date";
103:
104: /**
105: * Last modification date.
106: */
107: public static final String LAST_MODIFIED = "getlastmodified";
108:
109: /**
110: * Last modification date.
111: */
112: public static final String ALTERNATE_LAST_MODIFIED = "last-modified";
113:
114: /**
115: * Name.
116: */
117: public static final String NAME = "displayname";
118:
119: /**
120: * Type.
121: */
122: public static final String TYPE = "resourcetype";
123:
124: /**
125: * Type.
126: */
127: public static final String ALTERNATE_TYPE = "content-type";
128:
129: /**
130: * Source.
131: */
132: public static final String SOURCE = "source";
133:
134: /**
135: * MIME type of the content.
136: */
137: public static final String CONTENT_TYPE = "getcontenttype";
138:
139: /**
140: * Content language.
141: */
142: public static final String CONTENT_LANGUAGE = "getcontentlanguage";
143:
144: /**
145: * Content length.
146: */
147: public static final String CONTENT_LENGTH = "getcontentlength";
148:
149: /**
150: * Content length.
151: */
152: public static final String ALTERNATE_CONTENT_LENGTH = "content-length";
153:
154: /**
155: * ETag.
156: */
157: public static final String ETAG = "getetag";
158:
159: /**
160: * Collection type.
161: */
162: public static final String COLLECTION_TYPE = "<collection/>";
163:
164: /**
165: * HTTP date format.
166: */
167: protected static final SimpleDateFormat format = new SimpleDateFormat(
168: "EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
169:
170: /**
171: * Date formats using for Date parsing.
172: */
173: protected static final SimpleDateFormat formats[] = {
174: new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz",
175: Locale.US),
176: new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy",
177: Locale.US),
178: new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz",
179: Locale.US),
180: new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US) };
181:
182: // ----------------------------------------------------------- Constructors
183:
184: /**
185: * Default constructor.
186: */
187: public ResourceAttributes() {
188: }
189:
190: /**
191: * Merges with another attribute set.
192: */
193: public ResourceAttributes(Attributes attributes) {
194: this .attributes = attributes;
195: }
196:
197: // ----------------------------------------------------- Instance Variables
198:
199: /**
200: * Collection flag.
201: */
202: protected boolean collection = false;
203:
204: /**
205: * Content length.
206: */
207: protected long contentLength = -1;
208:
209: /**
210: * Creation time.
211: */
212: protected long creation = -1;
213:
214: /**
215: * Creation date.
216: */
217: protected Date creationDate = null;
218:
219: /**
220: * Last modified time.
221: */
222: protected long lastModified = -1;
223:
224: /**
225: * Last modified date.
226: */
227: protected Date lastModifiedDate = null;
228:
229: /**
230: * Name.
231: */
232: protected String name = null;
233:
234: /**
235: * Weak ETag.
236: */
237: protected String weakETag = null;
238:
239: /**
240: * Strong ETag.
241: */
242: protected String strongETag = null;
243:
244: /**
245: * External attributes.
246: */
247: protected Attributes attributes = null;
248:
249: // ------------------------------------------------------------- Properties
250:
251: /**
252: * Is collection.
253: */
254: public boolean isCollection() {
255: if (attributes != null) {
256: return (getResourceType().equals(COLLECTION_TYPE));
257: } else {
258: return (collection);
259: }
260: }
261:
262: /**
263: * Set collection flag.
264: *
265: * @return value of the collection flag
266: */
267: public void setCollection(boolean collection) {
268: this .collection = collection;
269: if (attributes != null) {
270: String value = "";
271: if (collection)
272: value = COLLECTION_TYPE;
273: attributes.put(TYPE, value);
274: }
275: }
276:
277: /**
278: * Get content length.
279: *
280: * @return content length value
281: */
282: public long getContentLength() {
283: if (contentLength != -1L)
284: return contentLength;
285: if (attributes != null) {
286: Attribute attribute = attributes.get(CONTENT_LENGTH);
287: if (attribute != null) {
288: try {
289: Object value = attribute.get();
290: if (value instanceof Long) {
291: contentLength = ((Long) value).longValue();
292: } else {
293: try {
294: contentLength = Long.parseLong(value
295: .toString());
296: } catch (NumberFormatException e) {
297: ; // Ignore
298: }
299: }
300: } catch (NamingException e) {
301: ; // No value for the attribute
302: }
303: }
304: }
305: return contentLength;
306: }
307:
308: /**
309: * Set content length.
310: *
311: * @param contentLength New content length value
312: */
313: public void setContentLength(long contentLength) {
314: this .contentLength = contentLength;
315: if (attributes != null)
316: attributes.put(CONTENT_LENGTH, new Long(contentLength));
317: }
318:
319: /**
320: * Get creation time.
321: *
322: * @return creation time value
323: */
324: public long getCreation() {
325: if (creation != -1L)
326: return creation;
327: if (creationDate != null)
328: return creationDate.getTime();
329: if (attributes != null) {
330: Attribute attribute = attributes.get(CREATION_DATE);
331: if (attribute != null) {
332: try {
333: Object value = attribute.get();
334: if (value instanceof Long) {
335: creation = ((Long) value).longValue();
336: } else if (value instanceof Date) {
337: creation = ((Date) value).getTime();
338: creationDate = (Date) value;
339: } else {
340: String creationDateValue = value.toString();
341: Date result = null;
342: // Parsing the HTTP Date
343: for (int i = 0; (result == null)
344: && (i < formats.length); i++) {
345: try {
346: result = formats[i]
347: .parse(creationDateValue);
348: } catch (ParseException e) {
349: ;
350: }
351: }
352: if (result != null) {
353: creation = result.getTime();
354: creationDate = result;
355: }
356: }
357: } catch (NamingException e) {
358: ; // No value for the attribute
359: }
360: }
361: }
362: return creation;
363: }
364:
365: /**
366: * Set creation.
367: *
368: * @param creation New creation value
369: */
370: public void setCreation(long creation) {
371: this .creation = creation;
372: this .creationDate = null;
373: if (attributes != null)
374: attributes.put(CREATION_DATE, new Date(creation));
375: }
376:
377: /**
378: * Get creation date.
379: *
380: * @return Creation date value
381: */
382: public Date getCreationDate() {
383: if (creationDate != null)
384: return creationDate;
385: if (creation != -1L) {
386: creationDate = new Date(creation);
387: return creationDate;
388: }
389: if (attributes != null) {
390: Attribute attribute = attributes.get(CREATION_DATE);
391: if (attribute != null) {
392: try {
393: Object value = attribute.get();
394: if (value instanceof Long) {
395: creation = ((Long) value).longValue();
396: creationDate = new Date(creation);
397: } else if (value instanceof Date) {
398: creation = ((Date) value).getTime();
399: creationDate = (Date) value;
400: } else {
401: String creationDateValue = value.toString();
402: Date result = null;
403: // Parsing the HTTP Date
404: for (int i = 0; (result == null)
405: && (i < formats.length); i++) {
406: try {
407: result = formats[i]
408: .parse(creationDateValue);
409: } catch (ParseException e) {
410: ;
411: }
412: }
413: if (result != null) {
414: creation = result.getTime();
415: creationDate = result;
416: }
417: }
418: } catch (NamingException e) {
419: ; // No value for the attribute
420: }
421: }
422: }
423: return creationDate;
424: }
425:
426: /**
427: * Creation date mutator.
428: *
429: * @param creationDate New creation date
430: */
431: public void setCreationDate(Date creationDate) {
432: this .creation = creationDate.getTime();
433: this .creationDate = creationDate;
434: if (attributes != null)
435: attributes.put(CREATION_DATE, creationDate);
436: }
437:
438: /**
439: * Get last modified time.
440: *
441: * @return lastModified time value
442: */
443: public long getLastModified() {
444: if (lastModified != -1L)
445: return lastModified;
446: if (lastModifiedDate != null)
447: return lastModifiedDate.getTime();
448: if (attributes != null) {
449: Attribute attribute = attributes.get(LAST_MODIFIED);
450: if (attribute != null) {
451: try {
452: Object value = attribute.get();
453: if (value instanceof Long) {
454: lastModified = ((Long) value).longValue();
455: } else if (value instanceof Date) {
456: lastModified = ((Date) value).getTime();
457: lastModifiedDate = (Date) value;
458: } else {
459: String lastModifiedDateValue = value.toString();
460: Date result = null;
461: // Parsing the HTTP Date
462: for (int i = 0; (result == null)
463: && (i < formats.length); i++) {
464: try {
465: result = formats[i]
466: .parse(lastModifiedDateValue);
467: } catch (ParseException e) {
468: ;
469: }
470: }
471: if (result != null) {
472: lastModified = result.getTime();
473: lastModifiedDate = result;
474: }
475: }
476: } catch (NamingException e) {
477: ; // No value for the attribute
478: }
479: }
480: }
481: return lastModified;
482: }
483:
484: /**
485: * Set last modified.
486: *
487: * @param lastModified New last modified value
488: */
489: public void setLastModified(long lastModified) {
490: this .lastModified = lastModified;
491: this .lastModifiedDate = null;
492: if (attributes != null)
493: attributes.put(LAST_MODIFIED, new Date(lastModified));
494: }
495:
496: /**
497: * Set last modified date.
498: *
499: * @param lastModified New last modified date value
500: * @deprecated
501: */
502: public void setLastModified(Date lastModified) {
503: setLastModifiedDate(lastModified);
504: }
505:
506: /**
507: * Get lastModified date.
508: *
509: * @return LastModified date value
510: */
511: public Date getLastModifiedDate() {
512: if (lastModifiedDate != null)
513: return lastModifiedDate;
514: if (lastModified != -1L) {
515: lastModifiedDate = new Date(lastModified);
516: return lastModifiedDate;
517: }
518: if (attributes != null) {
519: Attribute attribute = attributes.get(LAST_MODIFIED);
520: if (attribute != null) {
521: try {
522: Object value = attribute.get();
523: if (value instanceof Long) {
524: lastModified = ((Long) value).longValue();
525: lastModifiedDate = new Date(lastModified);
526: } else if (value instanceof Date) {
527: lastModified = ((Date) value).getTime();
528: lastModifiedDate = (Date) value;
529: } else {
530: String lastModifiedDateValue = value.toString();
531: Date result = null;
532: // Parsing the HTTP Date
533: for (int i = 0; (result == null)
534: && (i < formats.length); i++) {
535: try {
536: result = formats[i]
537: .parse(lastModifiedDateValue);
538: } catch (ParseException e) {
539: ;
540: }
541: }
542: if (result != null) {
543: lastModified = result.getTime();
544: lastModifiedDate = result;
545: }
546: }
547: } catch (NamingException e) {
548: ; // No value for the attribute
549: }
550: }
551: }
552: return lastModifiedDate;
553: }
554:
555: /**
556: * Last modified date mutator.
557: *
558: * @param lastModifiedDate New last modified date
559: */
560: public void setLastModifiedDate(Date lastModifiedDate) {
561: this .lastModified = lastModifiedDate.getTime();
562: this .lastModifiedDate = lastModifiedDate;
563: if (attributes != null)
564: attributes.put(LAST_MODIFIED, lastModifiedDate);
565: }
566:
567: /**
568: * Get name.
569: *
570: * @return Name value
571: */
572: public String getName() {
573: if (name != null)
574: return name;
575: if (attributes != null) {
576: Attribute attribute = attributes.get(NAME);
577: if (attribute != null) {
578: try {
579: name = attribute.get().toString();
580: } catch (NamingException e) {
581: ; // No value for the attribute
582: }
583: }
584: }
585: return name;
586: }
587:
588: /**
589: * Set name.
590: *
591: * @param name New name value
592: */
593: public void setName(String name) {
594: this .name = name;
595: if (attributes != null)
596: attributes.put(NAME, name);
597: }
598:
599: /**
600: * Get resource type.
601: *
602: * @return String resource type
603: */
604: public String getResourceType() {
605: String result = null;
606: if (attributes != null) {
607: Attribute attribute = attributes.get(TYPE);
608: if (attribute != null) {
609: try {
610: result = attribute.get().toString();
611: } catch (NamingException e) {
612: ; // No value for the attribute
613: }
614: }
615: }
616: if (result == null) {
617: if (collection)
618: result = COLLECTION_TYPE;
619: else
620: result = "";
621: }
622: return result;
623: }
624:
625: /**
626: * Type mutator.
627: *
628: * @param resourceType New resource type
629: */
630: public void setResourceType(String resourceType) {
631: collection = resourceType.equals(COLLECTION_TYPE);
632: if (attributes != null)
633: attributes.put(TYPE, resourceType);
634: }
635:
636: /**
637: * Get ETag.
638: *
639: * @return Weak ETag
640: */
641: public String getETag() {
642: return getETag(false);
643: }
644:
645: /**
646: * Get ETag.
647: *
648: * @param strong If true, the strong ETag will be returned
649: * @return ETag
650: */
651: public String getETag(boolean strong) {
652: String result = null;
653: if (attributes != null) {
654: Attribute attribute = attributes.get(ETAG);
655: if (attribute != null) {
656: try {
657: result = attribute.get().toString();
658: } catch (NamingException e) {
659: ; // No value for the attribute
660: }
661: }
662: }
663: if (strong) {
664: // The strong ETag must always be calculated by the resources
665: result = strongETag;
666: } else {
667: // The weakETag is contentLenght + lastModified
668: if (weakETag == null) {
669: weakETag = "W/\"" + getContentLength() + "-"
670: + getLastModified() + "\"";
671: }
672: result = weakETag;
673: }
674: return result;
675: }
676:
677: /**
678: * Set strong ETag.
679: */
680: public void setETag(String eTag) {
681: this .strongETag = eTag;
682: if (attributes != null)
683: attributes.put(ETAG, eTag);
684: }
685:
686: // ----------------------------------------------------- Attributes Methods
687:
688: /**
689: * Get attribute.
690: */
691: public Attribute get(String attrID) {
692: if (attributes == null) {
693: if (attrID.equals(CREATION_DATE)) {
694: return new BasicAttribute(CREATION_DATE,
695: getCreationDate());
696: } else if (attrID.equals(ALTERNATE_CREATION_DATE)) {
697: return new BasicAttribute(ALTERNATE_CREATION_DATE,
698: getCreationDate());
699: } else if (attrID.equals(LAST_MODIFIED)) {
700: return new BasicAttribute(LAST_MODIFIED,
701: getLastModifiedDate());
702: } else if (attrID.equals(ALTERNATE_LAST_MODIFIED)) {
703: return new BasicAttribute(ALTERNATE_LAST_MODIFIED,
704: getLastModifiedDate());
705: } else if (attrID.equals(NAME)) {
706: return new BasicAttribute(NAME, getName());
707: } else if (attrID.equals(TYPE)) {
708: return new BasicAttribute(TYPE, getResourceType());
709: } else if (attrID.equals(ALTERNATE_TYPE)) {
710: return new BasicAttribute(ALTERNATE_TYPE,
711: getResourceType());
712: } else if (attrID.equals(CONTENT_LENGTH)) {
713: return new BasicAttribute(CONTENT_LENGTH, new Long(
714: getContentLength()));
715: } else if (attrID.equals(ALTERNATE_CONTENT_LENGTH)) {
716: return new BasicAttribute(ALTERNATE_CONTENT_LENGTH,
717: new Long(getContentLength()));
718: }
719: } else {
720: return attributes.get(attrID);
721: }
722: return null;
723: }
724:
725: /**
726: * Put attribute.
727: */
728: public Attribute put(Attribute attribute) {
729: if (attributes == null) {
730: try {
731: return put(attribute.getID(), attribute.get());
732: } catch (NamingException e) {
733: return null;
734: }
735: } else {
736: return attributes.put(attribute);
737: }
738: }
739:
740: /**
741: * Put attribute.
742: */
743: public Attribute put(String attrID, Object val) {
744: if (attributes == null) {
745: return null; // No reason to implement this
746: } else {
747: return attributes.put(attrID, val);
748: }
749: }
750:
751: /**
752: * Remove attribute.
753: */
754: public Attribute remove(String attrID) {
755: if (attributes == null) {
756: return null; // No reason to implement this
757: } else {
758: return attributes.remove(attrID);
759: }
760: }
761:
762: /**
763: * Get all attributes.
764: */
765: public NamingEnumeration getAll() {
766: if (attributes == null) {
767: Vector attributes = new Vector();
768: attributes.addElement(new BasicAttribute(CREATION_DATE,
769: getCreationDate()));
770: attributes.addElement(new BasicAttribute(LAST_MODIFIED,
771: getLastModifiedDate()));
772: attributes.addElement(new BasicAttribute(NAME, getName()));
773: attributes.addElement(new BasicAttribute(TYPE,
774: getResourceType()));
775: attributes.addElement(new BasicAttribute(CONTENT_LENGTH,
776: new Long(getContentLength())));
777: return new RecyclableNamingEnumeration(attributes);
778: } else {
779: return attributes.getAll();
780: }
781: }
782:
783: /**
784: * Get all attribute IDs.
785: */
786: public NamingEnumeration getIDs() {
787: if (attributes == null) {
788: Vector attributeIDs = new Vector();
789: attributeIDs.addElement(CREATION_DATE);
790: attributeIDs.addElement(LAST_MODIFIED);
791: attributeIDs.addElement(NAME);
792: attributeIDs.addElement(TYPE);
793: attributeIDs.addElement(CONTENT_LENGTH);
794: return new RecyclableNamingEnumeration(attributeIDs);
795: } else {
796: return attributes.getIDs();
797: }
798: }
799:
800: /**
801: * Retrieves the number of attributes in the attribute set.
802: */
803: public int size() {
804: if (attributes == null) {
805: return 5;
806: } else {
807: return attributes.size();
808: }
809: }
810:
811: /**
812: * Clone the attributes object (WARNING: fake cloning).
813: */
814: public Object clone() {
815: return this ;
816: }
817:
818: /**
819: * Case sensitivity.
820: */
821: public boolean isCaseIgnored() {
822: return false;
823: }
824:
825: }
|