/****************************************************************************** * Copyright: GPL v3 * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see <http://www.gnu.org/licenses/>. * ******************************************************************************/ package dba.utils; import dbaCore.data.FunctionalDependency; import dbaCore.data.Key; import dbaCore.data.RelationSchema; import dbaCore.logic.Analysis.GeneralRelationCheck; import dbaCore.logic.Analysis.RelationInformation; import java.util.ArrayList; /** * Relation-inspection for the GUI */ public class RelationInspectorGui implements constants { private Localization locale; private RelationInformation checker; private String result; public RelationInspectorGui() { super(); checker = new GeneralRelationCheck(); locale = Localization.getInstance(); result = ""; } public String inspectRelation(RelationSchema schema) { String highestForm = "BCNF"; boolean schemaSanity; ArrayList<FunctionalDependency> violatingFds; ArrayList<FunctionalDependency> prevViolatingFds; schemaSanity = isSchemaSane(schema); // Don't inspect when Schema is not proper if (!schemaSanity) { return result; } // BCNF violatingFds = checker.checkForBCNF(schema); if (violatingFds.isEmpty()) { highestForm = "BCNF"; } prevViolatingFds = violatingFds; // Third NF if (!violatingFds.isEmpty()) { violatingFds = checker.checkForThirdNF(schema); if (violatingFds.isEmpty()) { highestForm = "3.NF"; addToResult(locale.getString("RI_NotBCNF1")); addToResult(locale.getString("RI_NotBCNF2")); tellViolatingFds(prevViolatingFds); } prevViolatingFds = violatingFds; } // Second NF if (!violatingFds.isEmpty()) { violatingFds = checker.checkForSecondNF(schema); if (violatingFds.isEmpty()) { highestForm = "2.NF"; addToResult(locale.getString("RI_Not3NF1")); addToResult(locale.getString("RI_Not3NF2")); tellViolatingFds(prevViolatingFds); } else { highestForm = "1.NF"; addToResult(locale.getString("RI_Not2NF1")); addToResult(locale.getString("RI_Not2NF2")); tellViolatingFds(violatingFds); } } addToResult(locale.getString("RI_HighestNF") + " " + highestForm); return result; } private boolean isSchemaSane(RelationSchema schema) { boolean sane = true; ArrayList<Key> candidateKeys = checker.getAllCandidateKeys(schema); Key primaryKey = checker.getPrimaryKey(schema); if (schema.getFunctionalDependencies().isEmpty()) { addToResult(locale.getString("RI_NoFd")); sane = false; } else { for (FunctionalDependency fd : schema.getFunctionalDependencies()) { if (fd.getSourceAttributes().isEmpty() || fd.getTargetAttributes().isEmpty()) { addToResult(locale.getString("RI_EmptyFDSide")); sane = false; break; } } } if (primaryKey.getAttributes().isEmpty()) { addToResult(locale.getString("RI_NoPk")); tellCandidateKeys(candidateKeys); sane = false; } else if (!checker.isKeyDeterminingEverything(schema, primaryKey)) { addToResult(locale.getString("RI_PkNotAllAttr")); sane = false; } else if (!checker.isCandidateKey(primaryKey.getAttributes(), candidateKeys)) { addToResult(locale.getString("RI_PkNoCk")); tellCandidateKeys(candidateKeys); } if (sane) { addToResult(locale.getString("RI_OK")); } else { addToResult(locale.getString("RI_Warn")); } return sane; } private void tellCandidateKeys(ArrayList<Key> candidateKeys) { if (candidateKeys.isEmpty()) { addToResult(locale.getString("RI_NoCk")); } else { addToResult(locale.getString("RI_Ck")); for (Key key : candidateKeys) { addToResult("* " + key.toString()); } } } private void tellViolatingFds(ArrayList<FunctionalDependency> violatingFds) { for (FunctionalDependency fd : violatingFds) { addToResult("* " + fd.toString()); } } private String addToResult(String sentence) { result = result + sentence + "\n"; return result; } }