001/*******************************************************************************
002The MIT License (MIT)
003
004Copyright (c) 2024 KILLCODING.COM
005
006Permission is hereby granted, free of charge, to any person obtaining a copy
007of this software and associated documentation files (the "Software"), to deal
008in the Software without restriction, including without limitation the rights
009to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
010copies of the Software, and to permit persons to whom the Software is
011furnished to do so, subject to the following conditions:
012
013The above copyright notice and this permission notice shall be included in
014all copies or substantial portions of the Software.
015
016THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
017IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
018FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
019AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
020LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
021OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
022THE SOFTWARE.
023*****************************************************************************/
024package com.killcoding.cache;
025
026import java.io.Serializable;
027import java.util.List;
028import java.util.Map;
029import java.io.FileOutputStream;
030import java.io.ObjectOutputStream;
031import java.util.Date;
032import java.io.File;
033import java.io.ByteArrayOutputStream;
034import java.io.IOException;
035import java.nio.file.Files;
036import java.nio.file.Paths;
037import java.io.ObjectInputStream;
038import java.io.ByteArrayInputStream;
039import java.io.OutputStream;
040import com.killcoding.tool.CommonTools;
041import com.killcoding.log.Logger;
042import com.killcoding.log.LoggerFactory;
043import java.security.NoSuchAlgorithmException;
044import com.killcoding.tool.FileTools;
045import com.killcoding.tool.CipherTools;
046
047/**
048 * This class is encrypting cache value
049 * */
050public class DataObject implements java.io.Serializable {
051
052        private static final Logger log = LoggerFactory.getLogger(DataObject.class);
053
054        private String path;
055
056    private final static String defaultAesKey = CommonTools.generateId(256);
057
058    private String aesKey = null;
059
060        private boolean useEncrypt = true;
061
062        public DataObject(String path) throws Exception {
063                super();
064                this.path = path;
065                this.aesKey = defaultAesKey;
066        }
067
068        public DataObject(String aesKey,String path) throws Exception {
069                super();
070                this.path = path;
071                if (CommonTools.isBlank(aesKey)) {
072                    useEncrypt = false;
073                } else {
074                        this.aesKey = aesKey;
075                        useEncrypt = true;
076                }
077        }
078
079        public Object getData() throws Exception {
080                byte[] encData = Files.readAllBytes(Paths.get(path));
081                byte[] dec = decrypt(encData);
082                ByteArrayInputStream bais = null;
083                ObjectInputStream oips = null;
084                try {
085                        bais = new ByteArrayInputStream(dec);
086                        oips = new ObjectInputStream(bais);
087                        return oips.readObject();
088                } finally {
089                        try {
090                                if (bais != null)
091                                        bais.close();
092                        } catch (Exception e) {
093                                Logger.systemError(DataObject.class,e.getMessage(),e);
094                        }
095                        try {
096                                if (oips != null)
097                                        oips.close();
098                        } catch (Exception e) {
099                                Logger.systemError(DataObject.class,e.getMessage(),e);
100                        }                       
101                }
102        }
103
104        public void setObject(Object data) throws Exception {
105            setObjectTo(data);
106        }
107
108        private void setObjectTo(Object data) throws Exception {
109                ByteArrayOutputStream baos = null;
110                ObjectOutputStream objectOut = null;
111                try {
112                        File file = new File(path);
113                        File parent = file.getParentFile();
114                        if (!parent.exists()) {
115                                parent.mkdirs();
116                        }
117                        baos = new ByteArrayOutputStream();
118                        objectOut = new ObjectOutputStream(baos);
119                        objectOut.writeObject(data);
120                        objectOut.flush();
121                        baos.flush();
122                        byte[] encBytes = encrypt(baos.toByteArray());
123                        Files.write(file.toPath(), encBytes);
124                } finally {
125                        try {
126                                if (objectOut != null)
127                                        objectOut.close();
128                        } catch (Exception e) {
129                                Logger.systemError(DataObject.class,e.getMessage(),e);
130                        }
131                        try {
132                                if (baos != null)
133                                        baos.close();
134                        } catch (Exception e) {
135                                Logger.systemError(DataObject.class,e.getMessage(),e);
136                        }
137                }
138        }
139
140        private byte[] encrypt(byte[] data) throws Exception {
141                if (useEncrypt) {
142                        return CipherTools.AESEncrypt(aesKey,data);
143                } else {
144                        return data;
145                }
146        }
147
148        private byte[] decrypt(byte[] encData) throws Exception {
149                if (useEncrypt) {
150                        return CipherTools.AESDecrypt(aesKey,encData);
151                } else {
152                        return encData;
153                }
154        }
155
156}