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