001/*
002 * Stallion Core: A Modern Web Framework
003 *
004 * Copyright (C) 2015 - 2016 Stallion Software LLC.
005 *
006 * This program is free software: you can redistribute it and/or modify it under the terms of the
007 * GNU General Public License as published by the Free Software Foundation, either version 2 of
008 * the License, or (at your option) any later version. This program is distributed in the hope that
009 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
011 * License for more details. You should have received a copy of the GNU General Public License
012 * along with this program.  If not, see <http://www.gnu.org/licenses/gpl-2.0.html>.
013 *
014 *
015 *
016 */
017
018package io.stallion.plugins.javascript;
019
020import com.fasterxml.jackson.annotation.JsonIgnore;
021import com.fasterxml.jackson.databind.annotation.JsonSerialize;
022import io.stallion.dataAccess.DataAccessRegistry;
023import io.stallion.dataAccess.MappedModel;
024import io.stallion.dataAccess.MappedModelBase;
025import io.stallion.dataAccess.ModelController;
026import io.stallion.utils.GeneralUtils;
027
028
029import java.time.Instant;
030import java.time.ZonedDateTime;
031import java.util.Date;
032import java.util.List;
033import java.util.Map;
034
035@JsonSerialize(using = JsModelSerializer.class)
036public abstract class BaseJavascriptModel extends MappedModelBase {
037    public static String table;
038    public abstract Map properties();
039    @JsonIgnore
040    public abstract String getBucketName();
041    @JsonIgnore
042    public abstract Map<String, String> getTypeMap();
043    @JsonIgnore
044    public abstract Map<String, BaseDynamicColumn> getDynamicProperties();
045    @JsonIgnore
046    public abstract List<String> getJsonIgnoredColumns();
047
048    @JsonIgnore
049    @Override
050    public ModelController getController() {
051        return DataAccessRegistry.instance().get(getBucketName());
052    }
053
054    public BaseJavascriptModel() {
055
056    }
057
058    public BaseJavascriptModel(Map<String, Object> values) {
059        for (String key: values.keySet()) {
060            put(key, values.get(key));
061        }
062    }
063
064    @Override
065    public boolean containsKey(Object key) {
066        if (getDynamicProperties().containsKey(key.toString())) {
067            return true;
068        }
069        return super.containsKey(key);
070    }
071
072    @Override
073    public Object get(Object key) {
074        if (getDynamicProperties().containsKey(key.toString())) {
075            BaseDynamicColumn col = getDynamicProperties().get(key.toString());
076            return col.func(this);
077        }
078        return super.get(key);
079    }
080
081    @Override
082    public Object put(String key, Object value) {
083        if (value == null) {
084            super.put(key, value);
085            return value;
086        }
087
088        if (getTypeMap().containsKey(key)) {
089            String type = getTypeMap().get(key);
090            switch (type) {
091                case "long":
092                    if (value instanceof Long) {
093                        break;
094                    } else if (value instanceof Integer) {
095                        value = new Long((Integer) value);
096                    } else if (value instanceof Number) {
097                        value = ((Number) value).longValue();
098                    } else {
099                        value = Long.parseLong(value.toString());
100                    }
101                    break;
102                case "integer":
103                    if (value instanceof Integer) {
104                        break;
105                    } else if (value instanceof Number) {
106                        value = ((Number)value).intValue();
107                    } else {
108                        value = Integer.parseInt(value.toString());
109                    }
110                    break;
111                case "boolean":
112                    if (value instanceof Boolean) {
113                        break;
114                    } else if (value instanceof Integer) {
115                        value = ((Integer)value == 1);
116                    } else if (value instanceof Long) {
117                        value = ((Long)value == 1);
118                    } else {
119                        value = value.toString().toLowerCase().equals("true");
120                    }
121                    break;
122                case "datetime":
123                    if (value instanceof ZonedDateTime) {
124                        break;
125                    } else if (value instanceof Date) {
126                        value = ((Date)value).toInstant().atZone(GeneralUtils.UTC);
127                    } else if (value instanceof java.sql.Date) {
128                        value = ((java.sql.Date)value).toInstant().atZone(GeneralUtils.UTC);
129                    } else if (value instanceof Long) {
130                        value = Instant.ofEpochMilli((Long)value).atZone(GeneralUtils.UTC);
131                    }
132            }
133        }
134        return super.put(key, value);
135
136    }
137}