001    package ezvcard.property;
002    
003    import java.io.File;
004    import java.io.IOException;
005    import java.io.InputStream;
006    import java.util.List;
007    
008    import ezvcard.VCard;
009    import ezvcard.VCardVersion;
010    import ezvcard.Warning;
011    import ezvcard.parameter.KeyType;
012    
013    /*
014     Copyright (c) 2013, Michael Angstadt
015     All rights reserved.
016    
017     Redistribution and use in source and binary forms, with or without
018     modification, are permitted provided that the following conditions are met: 
019    
020     1. Redistributions of source code must retain the above copyright notice, this
021     list of conditions and the following disclaimer. 
022     2. Redistributions in binary form must reproduce the above copyright notice,
023     this list of conditions and the following disclaimer in the documentation
024     and/or other materials provided with the distribution. 
025    
026     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
027     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
028     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
029     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
030     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
031     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
032     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
033     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
034     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
035     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
036    
037     The views and conclusions contained in the software and documentation are those
038     of the authors and should not be interpreted as representing official policies, 
039     either expressed or implied, of the FreeBSD Project.
040     */
041    
042    /**
043     * A public key for encryption.
044     * 
045     * <p>
046     * <b>Adding a key</b>
047     * </p>
048     * 
049     * <pre class="brush:java">
050     * VCard vcard = new VCard();
051     * 
052     * //URL (vCard 4.0 only; KEYs cannot have URLs in vCard 2.1 and 3.0)
053     * Key key = new Key("http://www.mywebsite.com/pubkey.pgp", KeyType.PGP);
054     * vcard.addKey(key);
055     * 
056     * //binary data
057     * byte data[] = ...
058     * key = new Key(data, KeyType.PGP);
059     * vcard.addKey(key);
060     * 
061     * //plain text value
062     * key = new Key();
063     * key.setText("...", KeyType.PGP);
064     * vcard.addKey(key);
065     * 
066     * //if "KeyType" does not have the pre-defined constant that you need, then create a new instance
067     * //arg 1: the value of the 2.1/3.0 TYPE parameter
068     * //arg 2: the value to use for the 4.0 MEDIATYPE parameter and for 4.0 data URIs
069     * //arg 3: the file extension of the data type (optional)
070     * KeyType param = new KeyType("mykey", "application/my-key", "mkey");
071     * key = new Key("http://www.mywebsite.com/pubkey.enc", param);
072     * vcard.addKey(key);
073     * </pre>
074     * 
075     * <p>
076     * <b>Getting the keys</b>
077     * </p>
078     * 
079     * <pre class="brush:java">
080     * VCard vcard = ...
081     * 
082     * int fileCount = 0;
083     * for (Key key : vcard.getKeys()){
084     *   //the key will have either a URL or a binary data
085     *   //only 4.0 vCards are allowed to use URLs for keys
086     *   if (key.getData() == null){
087     *     System.out.println("Key URL: " + key.getUrl());
088     *   } else {
089     *     KeyType type = key.getContentType();
090     *     
091     *     if (type == null) {
092     *       //the vCard may not have any content type data associated with the key
093     *       System.out.println("Saving a key file...");
094     *     } else {
095     *       System.out.println("Saving a \"" + type.getMediaType() + "\" file...");
096     *     }
097     *     
098     *     String folder;
099     *     if (type == KeyType.PGP){ //it is safe to use "==" instead of "equals()"
100     *       folder = "pgp-keys";
101     *     } else {
102     *       folder = "other-keys";
103     *     }
104     *     
105     *     byte data[] = key.getData();
106     *     String filename = "key" + fileCount;
107     *     if (type != null && type.getExtension() != null){
108     *      filename += "." + type.getExtension();
109     *     }
110     *     OutputStream out = new FileOutputStream(new File(folder, filename));
111     *     out.write(data);
112     *     out.close();
113     *     fileCount++;
114     *   }
115     * }
116     * </pre>
117     * 
118     * <p>
119     * <b>Property name:</b> {@code KEY}
120     * </p>
121     * <p>
122     * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0}
123     * </p>
124     * @author Michael Angstadt
125     */
126    public class Key extends BinaryProperty<KeyType> {
127            private String text;
128    
129            /**
130             * Creates an empty key property.
131             */
132            public Key() {
133                    super();
134            }
135    
136            /**
137             * Creates a key property.
138             * @param data the binary data
139             * @param type the type of key (e.g. PGP)
140             */
141            public Key(byte data[], KeyType type) {
142                    super(data, type);
143            }
144    
145            /**
146             * Creates a key property.
147             * @param url the URL to the key (vCard 4.0 only)
148             * @param type the type of key (e.g. PGP)
149             */
150            public Key(String url, KeyType type) {
151                    super(url, type);
152            }
153    
154            /**
155             * Creates a key property.
156             * @param in an input stream to the binary data (will be closed)
157             * @param type the content type (e.g. PGP)
158             * @throws IOException if there's a problem reading from the input stream
159             */
160            public Key(InputStream in, KeyType type) throws IOException {
161                    super(in, type);
162            }
163    
164            /**
165             * Creates a key property.
166             * @param file the key file
167             * @param type the content type (e.g. PGP)
168             * @throws IOException if there's a problem reading from the file
169             */
170            public Key(File file, KeyType type) throws IOException {
171                    super(file, type);
172            }
173    
174            /**
175             * Sets a plain text representation of the key.
176             * @param text the key in plain text
177             * @param type the key type
178             */
179            public void setText(String text, KeyType type) {
180                    this.text = text;
181                    data = null;
182                    url = null;
183                    setContentType(type);
184            }
185    
186            /**
187             * Gets the plain text representation of the key.
188             * @return the key in plain text
189             */
190            public String getText() {
191                    return text;
192            }
193    
194            @Override
195            protected void _validate(List<Warning> warnings, VCardVersion version, VCard vcard) {
196                    if (url == null && data == null && text == null) {
197                            warnings.add(new Warning(8));
198                    }
199    
200                    if (url != null && (version == VCardVersion.V2_1 || version == VCardVersion.V3_0)) {
201                            warnings.add(new Warning(15));
202                    }
203            }
204    }